1

我有一个区域基础设施建模如下:每个区域都有一个多对多的国家和可选的州(如果它是美国境内的一个区域)

from django.contrib.auth.models import User
from django.contrib.localflavor.us.models import USStateField
from django.db import models

from django_countries import CountryField


class CountryManager(models.Manager):
    def get_by_natural_key(self, country):
        return self.get(country=country)


class Country(models.Model):
    country = CountryField(unique=True)

    objects = CountryManager()

    class Meta:
        ordering = ('country',)

    def __unicode__(self):
        return unicode(self.country.name)

    def natural_key(self):
        return (self.country.code,)


class StateManager(models.Manager):
    def get_by_natural_key(self, state):
        return self.get(state=state)


class State(models.Model):
    state = USStateField(unique=True)

    objects = StateManager()

    class Meta:
        ordering = ('state',)

    def __unicode__(self):
        return self.get_state_display()

    def natural_key(self):
        return (self.state,)


class Region(models.Model):
    name = models.CharField(max_length=255, unique=True)
    coordinator = models.ForeignKey(User, null=True, blank=True)
    is_us = models.BooleanField('Is a US region')
    countries = models.ManyToManyField(Country)
    states = models.ManyToManyField(State, blank=True)

    class Meta:
        ordering = ('name',)

    def __unicode__(self):
        return self.name

每个用户都有一个定义(部分)如下的配置文件:

class UserProfile(models.Model):

    user = models.OneToOneField(User, related_name='user_profile')
    city = models.CharField(max_length=255)
    country = CountryField()
    state = USStateField(_(u'US only (determines user's region)'), blank=True, null=True)

我正在尝试按区域过滤一堆用户对象。所以我有

        region = Region.objects.filter(id=self.request.GET['filter_region'])
        if len(region) == 0:
            raise Exception("Region not found for filter")
        if len(region) > 1:
            raise Exception("Multiple regions found for filter?")
        region = region[0]

        queryset = queryset.filter(user_profile__country__in=region.countries.all)

可悲的是,这会返回一个空的查询集。我怀疑这与“国家”模型中有一个“国家”字段(可怕的模棱两可的命名,我知道,最初不是我的代码)有关,而且我只是按“国家”模型过滤,而不是其中的“国家”字段。(那有意义吗?)

如何按 ManyToMany 字段的子字段进行过滤?

4

1 回答 1

1

.filter()首先,如果您只想要一个项目,为什么要使用:

region = Region.objects.get(id=self.request.GET['filter_region'])

如果对象不存在,这将引发ObjectDoesNotExist异常,但如果查询集为空,则会引发异常。如果您需要捕获该异常,您可以使用try...except块或get_object_or_404在视图中。

其次,不要self.request.GET['filter_region']直接使用。如果未设置密钥,您将引发IndexError. 改用:

self.request.GET.get('filter_region')

现在,至于您的实际问题:UserProfile.countryis aCountryField这只是一个专门的CharField. 而Region.countries模型是 M2M Country。两者不可比,这就是您的查询集返回空的原因。

UserProfile.country一个外键Country,你就开始做生意了。

于 2012-02-02T15:22:40.997 回答