Django напишите Q-фильтр на основе элементов формы

Я хотел бы написать фильтр django для следующего сценария. CASE : У меня есть 4 чекбокса box1, box2, box3, box4 и кнопка submit на моей HTML странице.

Я написал модель post с 6 полями, где 4 поля соответствуют box1,2,3,4. На основе пользовательского ввода (4 флажка) она должна фильтровать пост. Однако означает ли это, что я должен написать 16 сценариев 4x4. или можно сформулировать это лучше. конечно, используя if elif

post.objects.filter(Q(id=1),Q(sid=1),Q(pid=1),Q(kid=1)) # case 1
post.objects.filter(Q(id=1),Q(sid=1))
post.objects.filter(Q(id=1),Q(kid=1))
post.objects.filter(Q(id=1),Q(pid=1))
post.objects.filter(Q(kid=1),Q(sid=1))
.
.
.
post.objects.filter(Q(kid=1))

Есть ли лучший способ сделать это?

Нет. Вы можете построить набор запросов фильтр за фильтром на основе ввода формы.

qs = Post.objects.all()
if form.cleaned_data['id']:  # I don't know what you have called the form fields
    qs = qs.filter(Q(id=1))
if form.cleaned_data['kid']:
    qs = qs.filter(Q(kid=1))
if form.cleaned_data['pid']:
    qs = qs.filter(Q(pid=1))
if form.cleaned_data['sid']:
    qs = qs.filter(Q(sid=1))

Обратите внимание, что для AND-логики вам не нужны Q-объекты. Вы можете просто использовать qs.filter( id=1 ).filter( sid=1).filter ...

Q-объекты необходимы, если вам нужна логика OR, в этом случае вы построите составной Q-объект из набора элементарных. Что-то вроде

qlist = []
if form.cleaned_data['id']:
   qlist.append( Q(id=1))
...
if qlist:
   qq = qlist[0]
   for q in qlist[1:]
      qq = qq | q      # OR-logic
   qs = qs.filter( qq)
Вернуться на верх