This is interesting. I think the two examples you give are distinct use cases and they should be. But I think it's just as common to want to do what felix is doing. Essentially he wants to modify a queryset as it exists by adding or overriding additional parameters. It can be very convenient to build this up as you go through the logic in your app. Felix ends up doing this manually by just holding all of his params in a dict and adding them at the end. But would it be a bad thing for django to support this use case out of the box? How about something like
Queryset.update(dict | **kwargs) so this qs = Model.objects.filter(a__b=x) qs = qs.update(a__c=y) Is equivalent to Model.objects.filter(a__b=x, a__c=y) It would still return a new query set to support chaining. But the new one would be built with a merging the of the old and new parameters rather than a "filter these and then filter these" type of structure. The name "update" conflicts with the api for dict.update which updates in place. Maybe that's okay or maybe it needs a new name. :Marco On Feb 22, 3:15 am, Russell Keith-Magee <freakboy3...@gmail.com> wrote: > On Mon, Feb 22, 2010 at 4:48 AM, felix <crucialfe...@gmail.com> wrote: > > > This seems so blatant that it couldn't really be a bug without someone > > noticing. Django 1.2 > > > qs = Apt.objects.filter(list_on_web=True,is_available=True) > > > # FastAdderStatus has Apt and Service as fk > > qs = qs.filter(fastadderstatus__service=self.service) > > > # later on here's another filter on the same table > > qs = qs.filter(fastadderstatus__running_status__in= (2, 3, 4)) > > > produces this: > > > SELECT U0."id" FROM "nsproperties_apt" U0 INNER JOIN > > "fastadder_fastadderstatus" U1 ON (U0."id" = U1."apt_id") INNER JOIN > > "fastadder_fastadderstatus" U3 ON (U0."id" = U3."apt_id") WHERE > > (U0."list_on_web" = True AND U0."is_available" = True AND > > U1."service_id" = 4 AND U3."running_status" IN (2, 3, 4)) > > > Note that it joins the same table twice, and the Apt is not returning > > distinct. Postgres is not liking the query. > > > count: 2837 > > > [<Apt: Property #12297>, <Apt: Property #12297>, <Apt: Property > > #12297>, <Apt: Property #12304>, <Apt: Property #12304>, <Apt: > > Property #12304>, <Apt: Property #12305>, <Apt: Property #12305>, > > <Apt: Property #12305>, <Apt: Property #12308>, <Apt: Property > > #12308>, <Apt: Property #12308>, <Apt: Property #12309>, <Apt: > > Property #12309>, <Apt: Property #12309>, <Apt: Property #12311>, > > <Apt: Property #12311>, <Apt: Property #12311>, <Apt: Property > > #12314>, <Apt: Property #12314>, '...(remaining elements > > truncated)...'] > > > what it should say (manually fixed) : > > > SELECT U0."id" FROM "nsproperties_apt" U0 INNER JOIN > > "fastadder_fastadderstatus" U1 ON (U0."id" = U1."apt_id") WHERE > > (U0."list_on_web" = True AND U0."is_available" = True AND > > U1."service_id" = 4 AND U1."running_status" IN (2, 3, 4)) > > > count: 611, no dups > > > My solution: > > > params = {} > > if self.service: > > params['fastadderstatus__service'] = self.service > > if self.agent: > > params['agents'] = self.agent > > > if self.status: > > > params.update( > > FastAdderStatus.objects.filter_params_for_status(self.status,'fastadderstat > > us') ) > > > # a single call to filter > > qs = qs.filter(**params) > > > which avoids the (?) bug and also is vastly more efficient. > > You haven't found a bug - Django is returning exactly what you asked > for. There is a difference between making the query: > > Model.objects.filter(a__b=x).filter(a__c=y) > > and the query: > > Model.objects.filter(a__b=x, a__c=y). > > In the first query, Django will use two different joins on the 'A' > table. In the second query, the join on 'A' will be reused. It sounds > like what you want is the second query. > > This behaviour is documented here [1]. > > [1]http://docs.djangoproject.com/en/dev/topics/db/queries/#spanning-mult... > > Yours, > Russ Magee %-) -- You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-us...@googlegroups.com. To unsubscribe from this group, send email to django-users+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-users?hl=en.