1

我有一个名为的模型Domain,如下所示:

class Domain(models.Model):
    """
    Model for storing the company domains
    """
    user = models.ForeignKey(
        User
    )
    host = models.CharField(
        null=False, verbose_name="Host", max_length=128, unique=True
    )

我想使用 Django 的通用视图对此进行 CRUD 操作。此模型中有一个字段需要用户输入,但外键字段不需要任何用户输入。如何从我的通用视图生成的表单中排除该字段,但为其分配当前经过身份验证的用户的值。

谢谢。

4

1 回答 1

2

看看 Russel 对本周早些时候在django-users 组上的类似问题的回答。

引用答案*:

表单和视图解决了不同的问题。

View 正在解决“我如何处理这个请求并将其转换为响应?”的问题。该表单正在解决“如何将此请求中的 POST 数据转换为模型对象(或更改为模型对象)?”的问题。

非常粗略地说,一个视图正在执行以下操作:

  1. 查看获取请求
  2. View 判断这是 GET 还是 POST
  3. 如果它是 POST,View 会要求 Form 将 Post 转换为模型更改
  4. 表单返回成功或失败
  5. View 响应 Form 的成功或失败。
  6. 视图返回响应。

表单的功能是视图功能的完整子集——因此,它是一个完全可互换的内部组件。

现在,在简单的情况下,View 可以猜测表单的所有默认值——它只需要知道你正在处理一个 Foo 模型,并且它可以构造一个默认的 Foo ModelForm。但是,如果您有更复杂的表单要求,您将需要自定义表单。

我们可以通过在 View 类上公开 ModelForm 的所有选项来实现这一点;但为了保持一切干净,我们将 ModelForm 隔离,并为 View 提供了一种方法来指定它将使用哪个 Form 类。

所以 - 为了涵盖排除字段的用例,您定义一个排除字段的 ModelForm,然后让 CreateView 知道您要使用的表单:

class CampaignForm(forms.ModelForm):


    class Meta:
        model = Campaign
        exclude = ('user', 'name', 'content_inlined')

class CreateCampaignView(CreateView):
    form_class = CampaignForm
    template_name = "forms/create.html"

我猜当您说“修复字段的值”时,您的意思是在保存新的 Campaign 实例之前设置 user、name 和 content_inlined 的值;为此,您需要在表单的表单处理逻辑中注入一些额外的代码:

class CreateCampaignView(CreateView):
    form_class = CampaignForm
    template_name = "forms/create.html"

    def form_valid(self, form):
        form.instance.user = ... (something meaningful.. e.g., self.request.user)
        return super(CreateCampaignView, self).form_valid(form)

这会覆盖表单有效时的默认行为,并设置额外的值。form_valid() 的 super() 实现将保存实例。

作为记录,这也可以通过覆盖 ModelForm 上的 save() 方法来完成——但是,如果你这样做,你会丢失请求对象,如果你试图将实例值设置为某些东西,你将需要它这是请求敏感的。

*原始答案集self.object.user而不是form.instance.user. 这给出了一个AttributeError所以我在上面改变了它。

于 2011-07-17T16:13:38.880 回答