2011-04-18 110 views
18

我想什麼做的是顯示一個單一的形式,讓用戶:如何將外鍵字段添加到Django中的ModelForm中?

  • 輸入文檔標題(從Document模型)
  • 選擇他們從下拉列表user_defined_code選擇之一(人口稠密通過在unique_codeUserDefinedCode模型)
  • 類型(存儲在Code模型)

我不知道如何去顯示字段中脫穎而出在一個窗體中點擊關鍵關係。我知道在視圖中,您可以使用document.code_set(例如)訪問當前document對象的相關對象,但我不知道如何將其應用於ModelForm。

我的模型:

class UserDefinedCode(models.Model): 
    name = models.CharField(max_length=8) 
    owner = models.ForeignKey(User) 

class Code(models.Model): 
    user_defined_code = models.ForeignKey(UserDefinedCode) 
    unique_code = models.CharField(max_length=15) 

class Document(models.Model): 
    title = models.CharField(blank=True, null=True, max_length=200) 
    code = models.ForeignKey(Code) 
    active = models.BooleanField(default=True) 

我的ModelForm

class DocumentForm(ModelForm): 
    class Meta: 
     model = Document 

回答

27

在問候的形式顯示的外鍵字段,您可以使用forms.ModelChoiceField和它傳遞一個查詢集。

所以,forms.py:

class DocumentForm(forms.ModelForm): 
    class Meta: 
     model = Document 

    def __init__(self, *args, **kwargs): 
     user = kwargs.pop('user','') 
     super(DocumentForm, self).__init__(*args, **kwargs) 
     self.fields['user_defined_code']=forms.ModelChoiceField(queryset=UserDefinedCode.objects.filter(owner=user)) 

views.py:

def someview(request): 
    if request.method=='post': 
     form=DocumentForm(request.POST, user=request.user) 
     if form.is_valid(): 
      selected_user_defined_code = form.cleaned_data.get('user_defined_code') 
      #do stuff here 
    else: 
     form=DocumentForm(user=request.user) 

    context = { 'form':form, } 

    return render_to_response('sometemplate.html', context, 
     context_instance=RequestContext(request)) 

從你的問題:

我知道在一個視圖中,您可以使用 document.code_set (例如)到 訪問 當前文檔對象的相關對象,但是I當然不是 如何將其應用於ModelForm。

實際上,您的Document對象不會有.code_set,因爲在您的文檔模型中定義了FK關係。它正在定義與Code多對一的關係,這意味着每個對象可以有多個Document對象,而不是相反。你的Code對象將有一個.document_set。你可以從文檔對象中做什麼訪問,它與使用document.code有關。

編輯:我認爲這將做你正在尋找。 (未經測試)

forms.py:

class DocumentForm(forms.ModelForm): 
    class Meta: 
     model = Document 
     exclude = ('code',) 

    def __init__(self, *args, **kwargs): 
     user = kwargs.pop('user','') 
     super(DocumentForm, self).__init__(*args, **kwargs) 
     self.fields['user_defined_code']=forms.ModelChoiceField(queryset=UserDefinedCode.objects.filter(owner=user)) 
     self.fields['unique_code']=forms.CharField(max_length=15) 

views.py:

def someview(request): 
    if request.method=='post': 
     form=DocumentForm(request.POST, user=request.user) 
     if form.is_valid(): 
      uniquecode = form.cleaned_data.get('unique_code') 
      user_defined_code = form.cleaned_data.get('user_defined_code') 
      doc_code = Code(user_defined_code=user_defined_code, code=uniquecode) 
      doc_code.save() 
      doc = form.save(commit=False) 
      doc.code = doc_code 
      doc.save() 
      return HttpResponse('success') 
    else: 
     form=DocumentForm(user=request.user) 

    context = { 'form':form, } 

    return render_to_response('sometemplate.html', context, 
     context_instance=RequestContext(request)) 

實際上你可能要創建代碼對象時,而不是該使用get_or_create。

doc_code = Code(user_defined_code=user_defined_code, code=uniquecode) 
+0

感謝您的幫助。我閱讀了ModelChoiceField的文檔,現在它很有意義。你知道我將如何在'unique_code'字段中顯示CharField(我的問題中的第三個重點)嗎?我已經略微減少了我的模型以使它們更易於閱讀,但基本上我有一個分配有計算機生成的唯一文檔代碼的文檔。每個用戶都可以創建一個單獨的用戶代碼,作爲它們所擁有的所有文檔的文檔代碼的前綴附加,因此是多個模型的原因。 – 2011-04-18 21:14:54

+0

@本S好吧,讓我看看。我將編輯我的帖子。 – DTing 2011-04-18 21:17:17

+0

這很好。謝謝你的幫助。 – 2011-04-22 16:51:42

相關問題