QuerySets in Dictionaries

S

scoopseven

I need to create a dictionary of querysets. I have code that looks
like:

query1 = Myobject.objects.filter(status=1)
query2 = Myobject.objects.filter(status=2)
query3 = Myobject.objects.filter(status=3)

d={}
d['a'] = query1
d['b'] = query2
d['c'] = query3

Is there a way to do this that I'm missing?

Thanks.
 
S

Simon Brunning

2009/11/12 scoopseven said:
I need to create a dictionary of querysets.  I have code that looks
like:

query1 = Myobject.objects.filter(status=1)
query2 = Myobject.objects.filter(status=2)
query3 = Myobject.objects.filter(status=3)

d={}
d['a'] = query1
d['b'] = query2
d['c'] = query3

Is there a way to do this that I'm missing?

Untested:

wanted = (('a', 1), ('b', 2), ('c', 2))
d = dict((key, Myobject.objects.filter(status=number)) for (key,
number) in wanted)
 
D

Diez B. Roggisch

scoopseven said:
I need to create a dictionary of querysets. I have code that looks
like:

query1 = Myobject.objects.filter(status=1)
query2 = Myobject.objects.filter(status=2)
query3 = Myobject.objects.filter(status=3)

d={}
d['a'] = query1
d['b'] = query2
d['c'] = query3

Is there a way to do this that I'm missing?


d = dict(a=Myobject.objects.filter(status=1),
b=Myobject.objects.filter(status=2),
c=Myobject.objects.filter(status=3))

Diez
 
S

Steven D'Aprano

I need to create a dictionary of querysets. I have code that looks
like:

query1 = Myobject.objects.filter(status=1)
query2 = Myobject.objects.filter(status=2)
query3 = Myobject.objects.filter(status=3)

d={}
d['a'] = query1
d['b'] = query2
d['c'] = query3

Is there a way to do this that I'm missing?

I don't understand your problem. Assuming Myobject is defined, and has
the appropriate attribute objects.filter, the above should work exactly
as you give it.

What is your actual problem? Are you asking for help in defining a
queryset?
 
S

scoopseven

I need to create a dictionary of querysets.  I have code that looks
like:
query1 = Myobject.objects.filter(status=1)
query2 = Myobject.objects.filter(status=2)
query3 = Myobject.objects.filter(status=3)
d={}
d['a'] = query1
d['b'] = query2
d['c'] = query3
Is there a way to do this that I'm missing?

I don't understand your problem. Assuming Myobject is defined, and has
the appropriate attribute objects.filter, the above should work exactly
as you give it.

What is your actual problem? Are you asking for help in defining a
queryset?

I actually had a queryset that was dynamically generated, so I ended
up having to use the eval function, like this...

d = {}
for thing in things:
query_name = 'thing_' + str(thing.id)
query_string = 'Thing.objects.filter(type=' + str(thing.id) +
').order_by(\'-date\')[:3]'
executable_string = query_name + ' = Thing.objects.filter
(type=' + str(thing.id) + ').order_by(\'-date\')[:3]'
exec(executable_string)
d[query_name] = eval(query_string)

And no, this is not based on user-generated input.

Thanks for the input.
 
D

Diez B. Roggisch

scoopseven said:
I need to create a dictionary of querysets. I have code that looks
like:
query1 = Myobject.objects.filter(status=1)
query2 = Myobject.objects.filter(status=2)
query3 = Myobject.objects.filter(status=3)
d={}
d['a'] = query1
d['b'] = query2
d['c'] = query3
Is there a way to do this that I'm missing?
I don't understand your problem. Assuming Myobject is defined, and has
the appropriate attribute objects.filter, the above should work exactly
as you give it.

What is your actual problem? Are you asking for help in defining a
queryset?

I actually had a queryset that was dynamically generated, so I ended
up having to use the eval function, like this...

d = {}
for thing in things:
query_name = 'thing_' + str(thing.id)
query_string = 'Thing.objects.filter(type=' + str(thing.id) +
').order_by(\'-date\')[:3]'
executable_string = query_name + ' = Thing.objects.filter
(type=' + str(thing.id) + ').order_by(\'-date\')[:3]'
exec(executable_string)
d[query_name] = eval(query_string)

And no, this is not based on user-generated input.

Why do you need this to use exec? And it seems that executable_string is
superflous - or do you want the side-effect? But then, you have the
results in d already.


query = Thing.objects.filter(type="%i" % thing.id).order_by('-date')[:3]

d[query_name] = query

As a rule of thumb: if you think you need exec, you don't.


Diez
 
S

Steven D'Aprano

I actually had a queryset that was dynamically generated, so I ended up
having to use the eval function, like this...

d = {}
for thing in things:
query_name = 'thing_' + str(thing.id)
query_string = 'Thing.objects.filter(type=' + str(thing.id) +
').order_by(\'-date\')[:3]'
executable_string = query_name + ' = Thing.objects.filter
(type=' + str(thing.id) + ').order_by(\'-date\')[:3]'
exec(executable_string)
d[query_name] = eval(query_string)


What an unmaintainable mess.

If I've understood it, you can make it less crap by (1) getting rid of
the unnecessary escaped quotes, (2) avoiding generating the same strings
multiple times, and (3) avoiding string concatenation.

d = {}
for thing in things:
expr = "Thing.objects.filter(type=%s).order_by('-date')[:3]"
expr = rhs % thing.id
name = "thing_%s" % thing.id
exec("%s = %s" % (name, expr))
d[name] = eval(expr)


What else can we do to fix it? Firstly, why are you creating local
variables "thing_XXX" (where XXX is the thing ID) *and* dictionary keys
of exactly the same name? I'm sure you don't need the local variables.
(If you think you do, you almost certainly don't.) That gets rid of the
exec.

Next, let's get rid of the eval:

d = {}
for thing in things:
x = thing.id
name = "thing_%s" % x
d[name] = Thing.objects.filter(type=x).order_by('-date')[:3]


About half the size, ten times the speed, and 1000 times the readability.

Unless I've missed something, you don't need either exec or eval.
 
S

scoopseven

I actually had a queryset that was dynamically generated, so I ended up
having to use the eval function, like this...
d = {}
for thing in things:
        query_name = 'thing_' + str(thing.id)
        query_string = 'Thing.objects.filter(type=' + str(thing.id) +  
').order_by(\'-date\')[:3]'
        executable_string = query_name + ' = Thing.objects.filter
(type=' + str(thing.id) + ').order_by(\'-date\')[:3]'
        exec(executable_string)
        d[query_name] = eval(query_string)

What an unmaintainable mess.

If I've understood it, you can make it less crap by (1) getting rid of
the unnecessary escaped quotes, (2) avoiding generating the same strings
multiple times, and (3) avoiding string concatenation.

d = {}
for thing in things:
    expr = "Thing.objects.filter(type=%s).order_by('-date')[:3]"
    expr = rhs % thing.id
    name = "thing_%s" % thing.id
    exec("%s = %s" % (name, expr))
    d[name] = eval(expr)

What else can we do to fix it? Firstly, why are you creating local
variables "thing_XXX" (where XXX is the thing ID) *and* dictionary keys
of exactly the same name? I'm sure you don't need the local variables.
(If you think you do, you almost certainly don't.) That gets rid of the
exec.

Next, let's get rid of the eval:

d = {}
for thing in things:
    x = thing.id
    name = "thing_%s" % x
    d[name] = Thing.objects.filter(type=x).order_by('-date')[:3]

About half the size, ten times the speed, and 1000 times the readability.

Unless I've missed something, you don't need either exec or eval.

Steven,

This worked like a charm! Thank you for your insight, it's greatly
appreciated.

Mark
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top