我想创建一个显示简单表单(从用户模型派生)的视图函数+模板,并捕获表单提交。如何在Django中使用通用视图?
我的用户模型是:
class User(models.Model):
email = models.EmailField(unique=True)
name = models.CharField(max_length=100)
我只需要捕获表单中的电子邮件字段。
我认为必须有一种使用通用表单的简单方法,但我不确定使用哪一种,也不知道如何使用。我知道如何做的唯一其他方式是:
1)显式创建UserForm,并使用单个视图函数分隔POST和GET请求。例如:
def contact(request):
if request.method == 'GET':
# display UserForm
....
elif request.method == 'POST':
# process form submission
....
2)创建两个视图(带有单独的URL) - 一个使用通用视图显示表单,另一个视图接收表单提交,例如:。
class contact(generic.DetailView):
# display form from User model
model = User
....
def submit(request):
# process form submission
....
所以,我的两个问题是:
答案 0 :(得分:1)
答案的第一部分:使用单一视图。如果您使用功能视图(这是迄今为止最简单的解决方案),则规范表单处理编辑视图如下所示:
def myview(request, instance_id, ...):
instance = get_object_or_404(pk=instance_id)
if request.method == "POST":
form = MyForm(request.POST, ..., instance=instance)
if form.is_valid():
# assuming a ModelForm
form.save()
return redirect(somewhere)
# invalid forms will be re-rendered with the error messages
else:
form = MyForm(instance=instance)
return render(request, "myapp/mytemplate.html", {"form": form})
对于创建视图,您只需删除所有instance_xxx部分。或者,您可以对创建和更新使用相同的视图,使instance_id
可选:
def myview(request, instance_id=None, ...):
if instance_id is not None:
instance = get_object_or_404(pk=instance_id)
else:
instance = None
if request.method == "POST":
form = MyForm(request.POST, ..., instance=instance)
if form.is_valid():
# assuming a ModelForm
form.save()
return redirect(somewhere)
# invalid forms will be re-rendered with the error messages
else:
form = MyForm(instance=instance)
return render(request, "myapp/mytemplate.html", {"form": form})
如果您想要基于类的通用视图they are documented here。我个人认为从通用的基于类的视图中获得很多东西(当你试图掌握分散在六个基类和mixins中的执行流程时最终会感到头疼)但是YMMV。
<强>更新强>
如果我想在将实例保存到数据库之前对数据进行一些处理(包括添加额外的字段),我会在哪里这样做?
最好在表单中除非您需要其他一些您不希望传递给表单的数据。对于所有表单,您可以在the validation stage处理数据。使用ModelForm,您还可以覆盖save()
方法本身:
class MyModelForm(forms.ModelForm):
class Meta:
model = MyModel
fields = ('whatever', 'something')
def save(self, commit=True):
""" Save user and create a pro account """
instance = super(MyModelForm, self).save(commit=False)
instance.something_else = 42
if commit:
instance.save()
return instance
答案 1 :(得分:0)
CreateView
可以根据您的要求完美运行,您只需要创建一种联系模式和success_url
形式,用户将在表单提交后重定向。它会将自动用户数据保存到模型中
class ContactView(generic.CreateView):
form_class = ContactForm
template_name = 'contact/index.html'
success_url = '/homepage/' . #Mention URL here
答案 2 :(得分:0)
这也可以仅使用CreateView
来完成。在email
中指定fields
,因为您只需要表单中的电子邮件字段。您还可以在{{1}处理提交的表单方法。
form_valid