我似乎无法找到一种方法来限制在对象上应用过滤器时返回的manytomany元素。如果有人能帮忙的话我真的很感激。
我们说我有以下型号:
## models.py
class Address(models.Model):
street = models.CharField(max_length=128)
city = models.CharField(max_length=128)
state_province = models.CharField(max_length=128)
zipcode = models.CharField(max_length=5)
country = models.CharField(max_length=128)
class Venue(models.Model):
address = models.ForeignKey(Address)
phone_number = models.CharField(max_length=10)
class Event(models.Model):
name = models.CharField(max_length=200)
description = models.TextField()
venues = models.ManyToManyField(Venue)
现在,如果我有一个活动将在两个场地进行,一个活动在一个场地如下(为简化说明而简化):
e1 = Event1
e2 = Event2
v1 = Venue1
v2 = Venue2
e1.venues.add(v1,v2)
e2.venues.add(v1)
我想生成一个查询集,它可以恢复在Venue1' Venue1'只有' Venue1'作为返回场地的那些活动。
我试过了
event_list = Event.objects.filter(venues__address__city='CityVenue1')
但 event_list [0] .venues.all()
返回' Venue1'和' Venue2'。
我的偏好是:
我的模板按如下方式遍历事件列表:
{% for event in event_list %}
<p>event.name
{% for venue in event.venues.all %}
at {{ venue.address.city }}
{% endfor %}
</p>
{% endfor %}
我希望它返回:
Event1 at CityVenue1
Event2 at CityVenue1
但目前我得到
Event1 at CityVenue1
at CityVenue2
Event2 at CityVenue1
提前感谢您的帮助。
答案 0 :(得分:0)
当然你回到了两个场地,你正在查询模板中的所有场地。
{% for venue in event.venues.all %}
这一行执行一个全新的查询,抓住该活动的所有场地。
相反;在你看来,做你的过滤器并明确地传递你感兴趣的场地:
target_venue = Venue.objects.get(address__city='CityVenue1')
event_list = target_venue.event_set.filter(name='EventName')
return render(request, 'events/event-list.html',
{'Events': event_list, 'Venue': target_venue})
然后在你的模板中,
{% for Event in Events %}
<p> {{ Event.name }} at {{ Venue.address.city }} </p>
{% endfor %}
编辑:通过@limelights
的建议改进答案 1 :(得分:-1)
为什么你想在一个查询集中全部?
Venue.objects.get(id=<id_venue1>).event_set.all()
应该在一个查询集中返回链接到venue1的所有事件,并且您可以在另一个查询集中包含venue1。
您也可以使用
Venue.objects.get(id=<id_venue1>).values('adress', 'phone_number', 'event__name', 'event__description')
得到类似下面的数组:
[
{ 'adress': '<venue1adress>', 'phone_number': '<venue1phone>', 'event__name': 'foo', 'event__description': 'I am a foo event'},
{ 'adress': '<venue1adress>', 'phone_number': '<venue1phone>', 'event__name': 'bar', 'event__description': 'I am a bar event'},
...
]
最后,我想,你也可以修改默认的查询集(因为它是一个python对象,而python对象可以做你想做的任何事情):
events_for_venur1 = Event.objects.filter(venues=venue1)
for event in events_for_venur1:
for venue in event.venue_set:
if venue != venue1:
venue = None
# Here your queryset is ready, but DO NOT try to save it in the DB !!