排除通用 CRUD 视图中的字段

发布于 2024-11-24 06:38:17 字数 428 浏览 1 评论 0原文

我有一个名为 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 操作。该模型中有一个字段需要用户输入,但外键字段不需要任何用户输入。如何从通用视图生成的表单中排除该字段,但为其分配当前经过身份验证的用户的值。

谢谢。

I have a model named Domain which looks like this:

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
    )

I'd like to use Django's generic views for doing CRUD operations on this. There is one field in this model that needs user input but the foreign key field doesn't need any user input. How can I exclude that field from the form that my generic view generates but assign it the value of the current authenticated user.

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

泪意 2024-12-01 06:38:18

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

引用答案*:

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

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

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

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

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

现在,在简单的情况下,视图可以猜测所有
表单的默认值——它需要知道的是你正在处理
有了 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"

我猜当你说“修复字段的值”时,你的意思是设置
保存新内容之前,用户、名称和 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() 实现将
保存实例。

根据记录,这也可以通过覆盖 save() 来完成
ModelForm 上的方法——但是,如果你这样做,你就会失去
请求对象,如果您尝试设置,则需要该对象
实例值是请求敏感的。

*原始答案设置self.object.user而不是form.instance.user。这会产生一个 AttributeError ,所以我在上面更改了它。

Have a look at Russel's answer to a similar question on the django-users group earlier this week.

Quoting the answer*:

Forms and Views solve different problems.

The View is solving the problem of "how do I handle this request and
convert it into a response?". The Form is solving the problem of "How
do I convert the POST data in this request into a model object (or a
change to a model object)?".

Very roughly, a view is doing the following:

  1. View gets a request
  2. View works out whether this is a GET or a POST
  3. If its a POST, View asks the Form to turn the Post into a model change
  4. Form returns success or failure
  5. View responds to the success or failure of the Form.
  6. View returns a response.

The functionality of the Form is a complete subset of the
functionality of the View -- and for this reason, it's a completely
interchangable internal component.

Now, in simple situations, it's possible for a View to guess all the
defaults for the form -- all it needs to know is that you're dealing
with a Foo model, and it can construct a default Foo ModelForm.
However, if you have more sophisticated form requirements, you're
going to need a customized Form.

We could have implemented this by exposing all the options of
ModelForm on the View class; but in order to keep everything clean, we
kept the ModelForm isolated, and provided the View with a way to
specify which Form class it's going to use.

So - to cover your use case of excluding fields, you define a
ModelForm that excludes the fields, then let the CreateView know the
form you want to use:

class CampaignForm(forms.ModelForm):


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

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

I'm guessing when you say "fix a values for a field", you mean setting
the values of user, name and content_inlined before you save the new
Campaign instance; to do this, you need to inject some extra code into
the form processing logic of the form:

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)

This overrides the default behavior when the form is valid, and sets
the extra values. The super() implementation of form_valid() will then
save the instance.

For the record, this could also be done by overriding the save()
method on the ModelForm -- however, if you do that, you lose the
request object, which you will need if you're trying to set the
instance values to something that is request-sensitive.

*the original answer set self.object.user instead of form.instance.user. This gives an AttributeError so I have changed it above.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文