Django - как написать собственный набор запросов для каждого поля вместо модели

Я хочу создать настраиваемое поле, чтобы при запросе поля фильтр всегда был __iexact.

Пример:

class Domain(models.Model):
    domain = models.IExactCharField()
    name = models.CharField()

Я хочу, чтобы запрос типа Domain.objects.filter('domain=newdomain') был переписан как Domain.objects.filter('domain__iexact=newdomain').

Я понимаю, что вы можете сделать это с помощью пользовательского менеджера, но я хочу добавить поле для добавления пользовательского менеджера. И если пользовательский менеджер уже определен, я хочу, чтобы функции менеджеров были связаны. Это возможно? Я смотрел на метод contribute_to_class и подумал, что у него может быть некоторый потенциал при определении поля.


person John Smith    schedule 07.06.2012    source источник


Ответы (1)


Приведенный ниже код не будет работать — к сожалению, lookup_type добавляется в другом месте (в QuerySet). загляну внутрь :)

class IExactCharField(models.CharField):
    def get_prep_lookup(self, lookup_type, value):
        return super(IExactCharField, self).get_prep_lookup('iexact', value)

Он обеспечивает точный поиск - вы можете в конечном итоге добавить проверку lookup_type перед ссылкой на суперкласс.

PS. Имейте в виду, что некоторые базы данных (SQLite) не поддерживают поиск строки Unicode без учета регистра.

РЕДАКТИРОВАТЬ: единственный обходной путь, который у меня есть, - сделать все поля домена строчными буквами при сохранении () или каком-либо сигнале сохранения.

person pielgrzym    schedule 07.06.2012
comment
Я тоже это заметил :) Я работаю над обходным путем, который использует заголовок submit_to_class а-ля stackoverflow.com/questions/609563/. выложу в ближайшее время. Спасибо за вашу помощь! - person John Smith; 07.06.2012
comment
Вопрос с пользовательским менеджером по-прежнему заключается в том, как определить внутри get_query_set() в вашем пользовательском менеджере, что фильтр ищет поле, которое должно быть точным? - person pielgrzym; 07.06.2012
comment
в основном, если запрос domain='', установите его как domain__iexact=''. если запрос domain__exact='' вызывает ошибку. Я делаю это, создавая собственный менеджер. Это добавляет вторую проблему: если пользовательский менеджер уже определен, как я могу это учесть. - person John Smith; 07.06.2012
comment
Как проверить запрос? Что касается другого менеджера - на ум приходит забавное решение - пользовательский подкласс models.Model (или миксин), который автоматически создаст подкласс существующего пользовательского менеджера и заменит существующий пользовательский менеджер на submit_to_class новым менеджером подкласса, который делает волшебство и есть суперкласс, который творит свою магию ;)) - person pielgrzym; 08.06.2012