我是Django的新手,正在使用这个项目来学习它。我可以保存日记记录,但是多对多关系不起作用。
此“创建”视图显示正确的格式,包括带有列出所有密码的多重选择框(来自密码模型)。提交表单时,不保存多对多记录,但日记可以保存。
我发现了很多不同的答案,其中一些是针对python 2.7的,但这是基于[Django文档] [1]的最简单的方法。任何帮助将不胜感激。
此外,该关系在“管理”部分中工作正常,所以我认为这与“表单”和/或“查看和保存”有关。
models.py
from django.db import models
from crypto.models import Crypto as CryptoModel
class Journal(models.Model):
title = models.CharField(max_length=200, help_text='Journal Title', blank=False, null=False)
content = models.TextField(max_length=2000, help_text='Journal Content (HTML OK)', blank=False, null=False)
crypto_id = models.ManyToManyField(CryptoModel, blank=True)
created = models.DateTimeField(help_text='Created', auto_now_add=True, null=True)
def __str__(self):
return self.title ## String for representing the Model object, usually name field or title
forms.py
from django.forms import ModelForm, ModelMultipleChoiceField, widgets
from journal.models import Journal as JournalModel
from crypto.models import Crypto as CryptoModel
class JournalForm(ModelForm):
# select multiple items box
cryptos = ModelMultipleChoiceField(widget=widgets.SelectMultiple(attrs={'size': 30}), queryset=CryptoModel.objects.all())
class Meta:
model = JournalModel
fields = [
"title",
"content",
]
labels = {
'title': 'Journal Title',
}
required = [
"title", # same as model
"content", # same as model
]
views.py
from journal.forms import JournalForm
from django.utils import timezone
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render, redirect, get_object_or_404
from journal.models import Journal as JournalModel
def Create(request):
if request.method == "POST":
form = JournalForm(request.POST) # form instance
context = {'form': form} # if errors, keep the form data on next page load
journal = form.save(commit=False) # False needed for many-to-many
journal.title = form.cleaned_data["title"]
journal.content = form.cleaned_data["content"]
journal.created = timezone.now()
journal.save() # save the form journal data, now we have a PK
form.save_m2m() # save the 'form' using ManytoMany method
return HttpResponseRedirect('/journal/')
form = JournalForm()
context = {'form': form}
return render(request, 'journal/create.html', context)
models.py 2
from django.db import models
from crypto.models import Crypto
class Journal(models.Model):
title = models.CharField(max_length=200, help_text='Journal Title', blank=False, null=False)
content = models.TextField(max_length=2000, help_text='Journal Content (HTML OK)', blank=False, null=False)
crypto_id = models.ManyToManyField(Crypto, blank=True)
created = models.DateTimeField(help_text='Created', auto_now_add=True, null=True)
def __str__(self):
return self.title ## String for representing the Model object, usually name field or title
forms.py 2
from django.forms import ModelForm, ModelMultipleChoiceField, widgets
from journal.models import Journal
from crypto.models import Crypto
class JournalForm(ModelForm):
# select multiple items box
cryptos = ModelMultipleChoiceField(widget=widgets.SelectMultiple(attrs={'size': 30}), queryset=Crypto.objects.all())
class Meta:
model = JournalModel
fields = [
"title",
"content",
"cryptos",
]
views.py 2
from journal.forms import JournalForm
from django.utils import timezone
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render, redirect, get_object_or_404
from journal.models import Journal
def Create(request):
if request.method == "POST":
form = JournalForm(request.POST) # form instance
context = {'form': form} # if errors, keep the form data on next page load
journal = form.save(commit=False) # False needed for many-to-many
journal.created = timezone.now()
journal.save() # save the form journal data, now we have a PK
journal.crypto_id.set(form.cleaned_data.get("cryptos")) # must be after "save"
form.save_m2m() # save the 'form' using ManytoMany method
return HttpResponseRedirect('/journal/')
form = JournalForm()
context = {'form': form}
return render(request, 'journal/create.html', context)
答案 0 :(得分:1)
希望这只是解决您的问题,但是在保存日记帐实例后的这一行 journal.crypto_id.set(form.cleaned_data.get(“ cryptos”))
答案 1 :(得分:0)
您已经将模型和表单字段称为不同的事物; Django不知道它们与同一领域有关。格式名称crypos
是正确的名称,您应该将模型字段重命名为该名称。
此外,您还没有在fields
列表中指定该字段,因此Django甚至不会尝试在模型上进行设置。
请注意,您不需要设置标题或内容,form.save
就是您要做的。
答案 2 :(得分:0)
谢谢阿卜杜拉,在VIEW中添加了“ journal.crypto_id.set(form.cleaned_data.get(“ cryptos”))”,即可解决此问题。 另外需要注意的是,必须在保存“新闻”表格之后但保存多对多之前。
我更新了上面的“ models.py 2”,“ forms.py 2”和“ views.py 2”部分。这是工作代码。
答案 3 :(得分:0)
随时欢迎您。 是的,但是在journal.save()之后。 并设置不需要从表单调用save()。