2013-02-20 82 views
0

我有以下模型結構,其中每個匠人與兩個屬性具有多對多關係;語言和紀律。在表格中,用戶可以通過過濾這些屬性來選擇一個Tradesman的子集。Django多對多查詢空表單和模型值

我想發生,就是:

  1. 如果用戶過濾器只有一個屬性,形式選擇所有 未經過濾的屬性。例如。如果選擇一種語言,但 將該規則留空,它不會過濾規則。
  2. 如果用戶過濾了一個商家沒有 一個集合(即它爲空)的語言,它將排除該商人。

我想我可以通過巴洛克式非pythonesque,非django方法從查詢中提取主鍵並使用它們來解決此問題,但寧可使用更簡潔的方法。

我認爲可以解決這個問題將是:

  1. 動態Django的過濾器,會掉落或包含取決於條件上的if-else邏輯
  2. 一個參數,會匹配一切(包括空值)我可以存儲在一個變量中,例如。

    return_everything=**everything()!** 
    Q(discipline__id__in=return_everything) 
    

我一直在尋找在Django的docmentation和計算器並不能找到做任何的方法。 感謝您的幫助。

models.py:

class Discipline(models.Model): 
    discipline=models.CharField(max_length=200, unique=True) 

class Language(models.Model): 
    language=models.CharField(max_length=200, unique=True) 

class Tradesman(models.Model): 
    discipline=models.ManyToManyField(Discipline, blank=True, null=True) 
    language=models.ManyToManyField(Language, blank=True, null=True) 

forms.py

class TradesmanForm(forms.Form): 
    #select all values to output in the form 
    discipline_all=.Discipline.objects.all() 
    language_all=Language.objects.all() 

    #declare form variables 
    discipline=forms.ModelMultipleChoiceField(queryset=discipline_all,required=False) 
    language=forms.ModelMultipleChoiceField(queryset=language_all,required=False) 

    #clean data 
    def clean(self) 
     cleaned_data=super(TradesmanForm, self).clean() 
     return cleaned_data 

views.py

def TrademanLookup(request) 
    if request.method == 'POST':  
     if form.is_valid() 
      discipline=form.cleaned_data['discipline'] 
      language=form.cleaned_data['language'] 
      ################################################# 
      # how can I make the below query dynamic,  # 
      # or else pass a variable into it that selects # 
      # everything, including nulls?     # 
      ################################################# 
      tradesman_return=Tradesman.objects.filter(
       Q(discipline__id__in=discipline), 
       Q(language__id__in=language) 
       ) 
      ...work with returned data... 
     else: 
      ...something else... 
    else: 
      ...something else... 

    return render_to_response('some.html','somevar':somevar) 

回答

1
def TrademanLookup(request) 
    if request.method == 'POST':  
     if form.is_valid() 
      discipline=form.cleaned_data['discipline'] 
      language=form.cleaned_data['language'] 
      query = [] 
      if disciplines: 
       query.append(Q(discipline__in=discipline)) 
      if language: 
       query.append(Q(language__in=language)) 

      if query:  
       tradesman_return=Tradesman.objects.filter(*query) 
      else: 
       tradesman_return=Tradesman.objects.all() 

      #...work with returned data... 

NB:它被認爲GoodPractice(TM)使用複數形式對於收藏(應該真的是「紀律」和「浪漫」 es「在Trademan模型和表單中。

NB2:該約定是使用all_lower_with_underscore名字的功能,所以你的觀點應該被命名爲「trademan_lookup」

+0

這樣的作品,太感謝了。關於NB,大寫的視圖是簡化鱈魚換行的錯字,但是不能在管理員中使用多個模型?由於這個原因,我一直在將我的模型名稱從複數變爲單數。假設這意味着這是最佳實踐。再次感謝你的幫助。 – sean 2013-02-21 02:17:43