【问题标题】:Add data to ModelForm object before saving保存前向 ModelForm 对象添加数据
【发布时间】:2013-06-12 04:40:21
【问题描述】:

假设我有一个如下所示的表单:

forms.py

class CreateASomethingForm(ModelForm):
    class Meta:
        model = Something
        fields = ['field2', 'field3', 'field4']

我希望表单具有这三个字段。但是我的Somethingclass 也有field1。我的问题是 - 如果我不使用 ModelForm 来收集数据,我如何将数据添加到 field1。我尝试做这样的事情,但它不起作用,我不确定解决这个问题的正确方法:

views.py

def create_something_view(request):
    if (request.method == 'POST'):
        # Create an object of the form based on POST data
        obj = CreateASomething(request.POST)
        # ** Add data into the blank field1 ** (Throwing an error)
        obj['field1'] = request.user
        # ... validate, save, then redirect 

我收到的错误是:

TypeError: 'CreateAClassForm' object does not support item assignment

在 Django 中,在保存之前将数据分配给 ModelForm 对象的正确方法是什么?

【问题讨论】:

    标签: django django-forms django-views


    【解决方案1】:
    form = CreateASomething(request.POST)
    if form.is_valid():
        obj = form.save(commit=False)
        obj.field1 = request.user
        obj.save()
    

    【讨论】:

    • 谢谢 - 我使用列表访问调用来获取对象的属性是一个愚蠢的错误。
    • 对于基于类的视图也可以override the form_valid method添加此类信息,然后调用super(MyView, self).form_valid(form)达到同样的效果。
    • 有没有办法覆盖表单的save方法来达到同样的效果?
    • 如果该字段是必填字段怎么办?它永远不会到达 form_valid()。
    • 谢谢你,太酷了!首先它给了我“必填字段”的错误,但我在模型中发送了该字段的属性“空白=真”。像魅力一样工作
    【解决方案2】:

    有时,该字段可能是必需的,这意味着您无法通过 form.is_valid()。在这种情况下,您可以将包含所有字段的 dict 对象传递给表单。

       if request.method == 'POST':
           data = {
            'fields1': request.user,
            'fields2': additional_data,
           }
           form = CreateASomethingForm(data)
    
        if form.is_valid():
            form.commit(save)
    

    【讨论】:

    • 如果说 fields1 是您搜索的对象,您将如何处理?我收到错误“选择一个有效的选择。该选择不是可用的选择之一'
    【解决方案3】:

    django官方给出的两种方式 链接:https://docs.djangoproject.com/en/3.0/topics/forms/modelforms/

    方法一]

    author = Author(title='Mr')
    form = PartialAuthorForm(request.POST, instance=author)
    form.save()
    

    方法二]

    form = PartialAuthorForm(request.POST)
    author = form.save(commit=False)
    author.title = 'Mr'
    author.save()
    

    【讨论】:

      【解决方案4】:

      这是一种更合适的添加数据的方法,特别是在测试期间使用:

      首先使用model_to_dict 函数将现有条目转换为字典

      from django.forms.models import model_to_dict
      
      ...
      
      valid_data = model_to_dict(entry)
      

      然后将新数据添加到这个字典中

      valid_data['finish_time'] = '18:44'
      

      这比在表单中设置值效果更好

      update_form.finish_time = '18:44'
      

      使用有效数据和实例创建表单

      update_form = UserEntryForm(valid_data, instance=entry)
      

      做任何你需要的断言:

      self.assertTrue(update_form.is_valid())
      entry = update_form.save()
      self.assertEqual(
          entry.status,
          1
      )
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-10-14
        • 2017-08-12
        • 2015-09-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多