python - 排除通用 CRUD View 中的字段

标签 python django django-views django-generic-views

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

谢谢。

最佳答案

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

引用答案*:

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.

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

关于python - 排除通用 CRUD View 中的字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6725080/

相关文章:

python - 当设置instance=object时,Django模型表单不会填充

python - 在 Django 中存储电话号码时,我应该将它们存储为原始数字还是使用 django.contrib.localflavor?

python - CSRF 攻击是否适用于 API?

django - django 中是否有像 Rails 中那样的 before_filter ?

python - Django:根据用户显示不同的内容

python - Django 类别及其子类别

python - Pandas 分组行值调整

python - 将 3 列(x、y、结果)Python Pandas DataFrame 转换为结果值的 DataFrame,其中 x(唯一)作为行,y(唯一)作为列

Python 将字典转换为数据框失败

python - @login_required 导致问题