开发者

Filter results of ManyToMany field in django

开发者 https://www.devze.com 2023-01-27 03:44 出处:网络
Hi I have a many 2 many field on a django object, Foo <=> Bar so if I filter by something like Foo.objects.filter(bar_name_contains=\'x\')

Hi I have a many 2 many field on a django object,

Foo <=> Bar

so if I filter by something like Foo.objects.filter(bar_name_contains='x') I expect to get all Foo objects with related Bar objects having a name containing x,

So in the template I loop round Foos, then round foos bars, BUT I get ALL bars for that foo, not just the ones filtered by the filter!

Any help appreciated


Updated, some example co开发者_JAVA百科de, a one to may for simplicity, same issue applies..

Models.py

class Foo(models.Model):  
    bob = models.CharField(max_length=255)  

class Bar(models.Model):  
    wibble = models.CharField(max_length=255)  
    foos   = models.ForeignKey('Foo')

So with the above objects I say something like...

foobar = Foo.objects.filter(bob__wibble__icontains='blagh')

I will pass to a template for rendering, and I expect to have all the foos with a bar matching the query, and ONLY the bars matching the query BUT I dont get that, I get all the foos with a bar matching the query AND every bar that has that foo as its Foriegn Key.

i.e. I have for one foo i have the bars [{'wibble':'blagh'},{'wibble':'blob'},{'wibble':twip'}]

I have the following in my template:

{% for bar in foobar.bar_set.all %}
    {{ bar.wibble }},
{% endfor %}

instead of just getting 'blagh,' i would get 'blagh,blob,twip'


You haven't shown any code, but it looks like you are filtering the Foo, not the Bar. So you get all Foos who have a Bar whose name is 'x' in amongst their list of bars, but you don't do anything to limit the Bars themselves to those that contain x.

You probably want to do it the other way round: use a filter expression on Bar to only get those where name='x', then iterate through the list of related Foos.

Edit after comment You still need to filter the Bars, not the foos. You can do the grouping in the template, when you iterate through. For example:

bars = Bar.objects.filter(wibble__icontains='blagh').order_by('foo').select_related()

{% for bar in bars %}
    {% ifchanged bar.foo %}{{ bar.foo.bob }}{% endifchanged %}
    {{ bar.wibble }},
{% endfor %}
0

精彩评论

暂无评论...
验证码 换一张
取 消