1

我似乎无法找到一种方法来限制在对象上应用过滤器时返回的多对多元素。如果有人能提供帮助,我将不胜感激。

假设我有以下模型:

## 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”作为这些事件的返回地点。

我努力了

event_list = Event.objects.filter(venues__address__city='CityVenue1')

但是 event_list[0].venues.all()

返回“Venue1”和“Venue2”。

我的偏好是:

  1. 过滤视图中的 Event 对象而不是 Venue 对象。
  2. 出于性能原因,不要通过模板中的标签/过滤器应用任何逻辑并将其留给视图以返回所需的查询集。

我的模板遍历事件列表如下:

{% 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

在此先感谢您的帮助。

4

2 回答 2

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 的建议改进

于 2013-07-30T07:51:31.300 回答
-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')以下方式获取类似 dicts 的数组:

[
  { '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 !!
于 2013-07-30T07:51:25.003 回答