如何使用模型表单

时间:2017-10-05 14:17:04

标签: python django

我想创建一个显示简单表单(从用户模型派生)的视图函数+模板,并捕获表单提交。如何在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
    ....

所以,我的两个问题是:

  • 可以以及如何仅使用通用视图来实现它?
  • 应该使用哪种通用视图?

3 个答案:

答案 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