Django: фильтр для get_foo_display в Queryset - PullRequest
12 голосов
/ 18 января 2011

Я пытался отфильтровать набор запросов на простой модели, но пока безуспешно.

Вот моя модель:

class Country(models.Model):
    COUNTRY_CHOICES = (
        ('FR', _(u'France')),
        ('VE', _(u'Venezuela')),
    )

    code = models.CharField(max_length=2, choices=COUNTRY_CHOICES)

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

И я хотел бы сделать что-то вроде:

Country.objects.filter(get_code_display__icontains="france")
Country.objects.filter(code__display__icontains="france")
Country.objects.filter(get_code_display__icontains="france")

Но ни один из вышеперечисленных не работает. Как вы фильтруете поле, которое имеет атрибут choices? Я думал, что переопределенный __unicode__ поможет, но я предполагаю, что что-то упустил.

Ответы [ 4 ]

22 голосов
/ 18 января 2011

Вы не можете сделать это. filter работает на уровне базы данных, и база данных ничего не знает о ваших длинных именах. Если вы хотите выполнить фильтрацию по значению, вам нужно сохранить это значение в базе данных.

Альтернативой является перевод значения обратно в код и фильтрация по нему:

country_reverse = dict((v, k) for k, v in COUNTRY_CHOICES)
Country.objects.filter(code=country_reverse['france'])
1 голос
/ 27 мая 2015

Вы можете поменять значения в конструкторе:

class PostFilter(django_filters.FilterSet):

    def __init__(self, data=None, queryset=None, prefix=None, strict=None):
        data = dict(data)
        if data.get('type'):
            data['type'] = Post.get_type_id(data['type'][0])

        super(PostFilter, self).__init__(data, queryset, prefix, strict)

    class Meta:
        model = Post
        fields = ['type']
0 голосов
/ 06 декабря 2017

Вы можете использовать Выбор

from model_utils import Choices

class Country(models.Model):
    COUNTRY_CHOICES = Choices((
        ('FR', _(u'France')),
        ('VE', _(u'Venezuela')),
    ))

    code = models.CharField(max_length=2, choices=COUNTRY_CHOICES)

и сделать запрос:

Country.objects.filter(code=Country.COUNTRY_CHOICES.france)
0 голосов
/ 20 ноября 2017

Вдохновленный этим ответом , я сделал следующее:

search_for = 'abc'

results = (
    [
        x for x, y in enumerate(COUNTRY_CHOICES, start=1) 
        if search_for.lower() in y[1].lower()
    ]
)

Country.objects.filter(code__in=results)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...