Python Django,保存 ModelForm
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22739701/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Django, save ModelForm
提问by manosim
I have created a model Studentwhich extends from the Django Userand is a foreign key to another model while it has an integer field called year. What i'm trying to do is to save a form, which has 2 fields. The one is the course idand the another one is the the integer field year. When I'm clicking submit, i'm getting an error Cannot assign "u'2'": "Student.course" must be a "Course" instance.
我创建了一个模型Student,它从Django User扩展而来,它是另一个模型的外键,而它有一个名为 year 的整数字段。我想要做的是保存一个表单,它有 2 个字段。一个是课程 ID,另一个是整数字段year。当我单击提交时,出现错误无法分配“u'2'”:“Student.course”必须是“课程”实例。
models.py
模型.py
class Student(models.Model):
user = models.OneToOneField(User)
course = models.ForeignKey(Course)
year = models.IntegerField(validators=[MinValueValidator(1),
MaxValueValidator(7)])
view.py
查看.py
def step3(request):
user = request.user
if request.method == 'POST':
form = SelectCourseYear(request.POST)
if form.is_valid():
form.save()
return render_to_response("registration/complete.html", RequestContext(request))
else:
form = SelectCourseYear()
return render(request, 'registration/step3.html',)
forms.py
表格.py
class SelectCourseYear(forms.ModelForm):
course = forms.CharField()
year = forms.IntegerField(required=True)
class Meta:
model = Student
fields = ['user', 'course', 'year']
采纳答案by Bibhas Debnath
You dont need to redefine fields in the ModelForm
if you've already mentioned them in the fields
attribute. So your form should look like this -
ModelForm
如果您已经在fields
属性中提到了它们,则不需要重新定义它们。所以你的表格应该是这样的 -
class SelectCourseYear(forms.ModelForm):
class Meta:
model = Student
fields = ['course', 'year'] # removing user. we'll handle that in view
And we can handle the form with ease in the view -
我们可以在视图中轻松处理表单 -
def step3(request):
user = request.user
if request.method == 'POST':
form = SelectCourseYear(request.POST)
if form.is_valid():
student = form.save(commit=False)
# commit=False tells Django that "Don't send this to database yet.
# I have more things I want to do with it."
student.user = request.user # Set the user object here
student.save() # Now you can send it to DB
return render_to_response("registration/complete.html", RequestContext(request))
else:
form = SelectCourseYear()
return render(request, 'registration/step3.html',)
回答by Brandon
course
has to be an instance of a Course model, not just the primary key of the instance. You can still accept an id in the form as a text input, but you're going to need to retrieve the actual course instance and assign the value.
course
必须是 Course 模型的实例,而不仅仅是实例的主键。您仍然可以接受表单中的 id 作为文本输入,但您将需要检索实际课程实例并分配值。
You'll need to verify that the course id is valid, so putting that code into the clean method isn't a bad idea. Notice also how the course
field is excluded here? Otherwise the form will expect it to be present. You also don't need to re-define the year field, as the ModelForm will inherit that field from the Student model.
您需要验证课程 ID 是否有效,因此将该代码放入 clean 方法中并不是一个坏主意。还要注意course
这里是如何排除该字段的?否则表单将期望它存在。您也不需要重新定义 year 字段,因为 ModelForm 将从 Student 模型继承该字段。
# forms.py
class SelectCourseYear(forms.ModelForm):
class Meta:
model = Student
exclude = ['user', 'course']
course_id = forms.IntegerField()
def __init__(self, *args, **kwargs):
self.user = kwargs.pop('user')
super(SelectCourseYear, self).__init__(*args, **kwargs)
def clean_course_id(self):
course_id = self.cleaned_data.get('course_id')
try:
self.course = Course.objects.get(pk=course_id)
except Course.DoesNotExist:
raise forms.ValidationError('Sorry, that course id is not valid.')
return course_id
def save(self, commit=True):
instance = super(SelectCourseYear, self).save(commit=False)
instance.course = self.course
instance.user = self.user
if commit:
instance.save()
return instance
# views.py
def step3(request):
if request.method == 'POST':
form = SelectCourseYear(request.POST or None, user=request.user)
if form.is_valid():
form.save()
return render_to_response("registration/complete.html",
RequestContext(request))
return render(request, 'registration/step3.html',)
Now, when you call .save()
on the model, the course field will be assigned an instance of Course
现在,当您调用.save()
模型时,课程字段将被分配一个实例Course