對於Django來說比較新,並試圖將M2M關係的標準實踐拼湊在一起。我已經有了模型和db平方。Django Forms - 多對多關係
對於這個例子,我在我的文章項目中編寫了一個應用程序,我試圖添加Categories。爲了簡單起見,文章有一個標題,正文,時間戳(不包含在表單中)和類別。我更喜歡複選框來表示文章可以屬於的一個或多個類別。
到目前爲止,我有:
models.py
class Category(models.Model):
category = models.CharField(max_length=100)
def __unicode__(self):
return self.category
class Article(models.Model):
title = models.CharField(max_length=200)
body = models.TextField()
pub_date = models.DateTimeField(auto_now_add=True)
category = models.ManyToManyField(Category)
def __unicode__(self):
return self.title
views.py
def article_index(request):
return render_to_response('article_index.html', {'articles': Article.objects.all()})
def article_detail(request, article_id=1):
return render_to_response('article_detail.html', {'article': Article.objects.get(id=article_id)})
def article_create(request):
if request.method == 'POST': # If the form has been submitted...
form = ArticleForm(request.POST) # A form bound to the POST data
if form.is_valid(): # All validation rules pass
article = Article.objects.create(
title=form.cleaned_data['title'],
body=form.cleaned_data['body'],
category=form.cleaned_data['category']
)
return redirect('article_index') # Redirect after POST
else:
form = ArticleForm() # An unbound form
return render(request, 'article_form.html', { 'form': form })
forms.py
class ArticleForm(forms.Form):
title = forms.CharField(required=True)
body = forms.CharField(required=True, widget=forms.Textarea)
category = forms.MultipleChoiceField(Category.objects.all(), widget=forms.CheckboxSelectMultiple)
兩個項目的我目前卡住的是:
1)在視圖'article_create'中,我不確定如何創建類別作爲Article對象的一部分。在shell中,我必須通過調用save()來創建文章,然後添加每個類別。我是否需要在這裏做類似的事情,例如創建文章,然後遍歷每個類別?示例代碼表示讚賞。
2)尚未編碼'article_edit',假設它與創建高度相似,但我不確定是否需要處理用於將以前選擇的類別與當前提交進行比較的邏輯。或者,我是否應該刪除正在編輯的文章的所有類別條目,並根據當前的提交重新輸入它們?這可能是最簡單的。再次,這樣的示例代碼將有所幫助。
謝謝!
你也可以爲'article_create'和'article_edit'創建一個通用的方法,使得你沒有相同的邏輯兩次,但除此之外,我認爲它運行良好......並且只是將'instance'作爲'None'傳遞爲默認值。 – jheld
非常感謝這樣的詳細回覆。我會將此標記爲正確的答案。對於您爲未來讀者的利益做一個快速更新,請注意一點:在'class ArticleForm(forms.ModelForm)'中:'需要在該類定義的其餘部分之前有'class Meta:'行。 – David