Sorry, for a late reply.

Personally I don't feel that it's a particularly common need, but I can see 
> your use case. More common is that a reasonable filter is applicable - say 
> books with a rating over 80.
>

Yeah, I thought about using some other filter but it's a bit harder to 
control the number of results that way. You can get more or less than you 
want if you can't predict the contents of the database. This makes sense in 
some situations but in others, like in mine, you just want top N results, 
no matter what they are and getting that with a filter is just a cumbersome 
workaround for something that can be easily expressed in SQL.

As far as I know we don't have any support for SQL intersects and I don't 
> believe there are any plans to introduce it.
>

OK. My bad. I was under impression that you can get an INTERSECT with 
something like 

Book.objects.filter(id__gt = 100) & Book.objects.filter(id = 300)

But looking at the SQL now I see that this simply combines the conditions 
with AND and that something like this fails:

Book.objects.filter(id__gt = 100)[:10] & Book.objects.filter(id = 300)

In that case the solution is not as straightforward as I originally thought.

I do agree that this should be both documented and preferably raise an 
> error - please open a ticket.
>

OK.

The obvious nicety handled by 
> ModelChoiceField is the transformation from ids back to objects; the less 
> obvious one is that a ModelChoiceField runs the query anew for every form; 
> your ChoiceField cannot be initialized by a query in its definition, and 
> needs 
> to have its choices set in the form's __init__(). 
>

Thanks, good to know. I actually do want the instance to make this query, 
not the class as since the content of my table is not entirely constant.

I can also add another gotcha to your list - if you fetch objects in class 
definition, the query is performed before the test runner can switch 
database to TEST_DATABASE so the data comes from the default database. I 
ran into this when trying to set 'initial' and it was breaking my tests. I 
have to move it to __init__().

you can base your condition on some subquery, for instance :
>
> class BookForm(forms.Form):
>         book = forms.ModelChoiceField(
> queryset=Book.objects.filter(pk__in=Book.objects.order_by('-
> rating')[:100].values_list('pk')))
>
> I don't know if there is a better way to do that...
>

Thanks, that's a really nifty workaround. I thought that something like 
this would make two queries but I see that Django is smart enough to 
combine it into a single query with a subquery. Nice. A great thing is that 
I don't see any downsides to it except that it's a bit less clear than 
doing the limit in the main query. And I think that it shouldn't really 
degrade performance as the outer query is trivial.

Maybe having the from detect LIMIT and do something like this internally 
would be a good way to handle this in the Form class?

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/044f428c-8192-48ff-8619-21b22833a7fd%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to