Форум сайта python.su
Следующая проблема
Пользователь вводит различные критерии поиска. Если он их вводит - то ищем по этим критериям(принимают участие в select -filter посредством Q)
Если не вводит - то по ним не ищем.
Запрос вида select * from table_name where col1=val1 and col2=val2 and ….. and coln in ()… and ….
Как сие правильно перевести на джанговский ORM?
Пока что делаю тупым путём.
if q_1:
location_str = "Q(location__in=[%s])," % ",".join([str(cur.id) for cur in q_1])
if sform.cleaned_data['has_photo']:
photo_str = "~Q(ph1='') | ~Q(ph2='') | ~Q(ph3='') | ~Q(ph4=''),"
if sform.cleaned_data['description']:
descr_str = "Q(description__contains=sform.cleaned_data['description']),"
if sform.cleaned_data['publisher']:
publisher_str = "Q(user_id=sform.cleaned_data['publisher'].id),"
......................
exec("""q_object = Object.objects.filter(
%(location_str)s
%(photo_str)s
%(descr_str)s
%(publisher_str)s
.................
)""" % { 'location_str': location_str, 'descr_str': descr_str, 'publisher_str': publisher_str, 'photo_str': photo_str, ...}
)
Офлайн
m3ouПравильно думали, так и делайте. Это правильный путь. И конечно никаких exec.
Думал сделать с помощью распаковки аргументов ** или * , да вот в качестве каждого аргумента идёт Q или ~Q….
Офлайн
Daevaorn
Эээ, ты понял что он хотел?
ЗЫ: Я об код чуть глаза не сломал. Почему у переменных такие странные названия?
Отредактировано (Сен. 2, 2009 23:13:00)
Офлайн
FerromanЗменить кодогенерацию на обычные языковые конструкции:-)
Эээ, ты понял что он хотел?
Офлайн
Зменить кодогенерацию на обычные языковые конструкции:-)Именно. Так красиво сказать не получилось - опыта маловато :)
Тут нужно заредьюсить все условия в один объект Q и его передать в filter.А чуток поконкретнее? Как заредьюсить? Разве не для того был написан Q, чтобы он использовался в одном фильтре несколько раз, только применялся
Отредактировано (Сен. 2, 2009 23:37:26)
Офлайн
m3ouОбъект Q это обертка над оператором сравнения. Но обертка не простая - она может содержать в себе “дерево” из других таких же объектов. В общем, если захотите, то можете код Джанги на досуге почитать.
Разве не для того был написан Q, чтобы он использовался в одном фильтре несколько раз, только применялся
к разным полям…
q = Q()
if q_1:
q &= Q(location__in=q_1)
if sform.cleaned_data['has_photo']:
q &= ~Q(ph1='') | ~Q(ph2='') | ~Q(ph3='') | ~Q(ph4='')
if sform.cleaned_data['description']:
q &= Q(description__contains=sform.cleaned_data['description'])
if sform.cleaned_data['publisher']:
q &= Q(user=sform.cleaned_data['publisher'])
objects = Object.objects.filter(q)
Офлайн
attributes =
Object.objects.filter(reduce(or_, , value=item) for item in attributes]))
Офлайн
Спасибо огромное, теперь картина прояснилась
Офлайн