【问题标题】:Custom Django Model Form Field that Aggregates Multiple Instances of an Input聚合输入的多个实例的自定义 Django 模型表单字段
【发布时间】:2020-01-15 21:10:16
【问题描述】:

我在模型表单中创建了一个自定义字段,我希望使用该字段使用户能够输入多个输入实例。例如,自定义字段是对应于多个日期的一系列值。提交表单后,我想将所有这些值合并到一个字符串中,并将它们存储在单个数据库字段中。请参阅下面的代码。当我向输入添加多个值时,cleaned_data 字段为空。我想我需要在将输入数据传递给cleaned_data之前访问它,但我不确定如何。任何援助将不胜感激。

#forms.py
class UpdateModelForm(forms.ModelForm):
    custom_field = forms.CharField()

    class Meta:
        model = Model

    def clean_custom_field(self):
        custom_field = self.cleaned_data['custom_field']
        return custom_field



    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        #I've tried to access the input fields here without success


#views.py    
class ModelView(UpdateView):
model = Model
form_class = UpdateModelForm
template_name = 'model_edit.html'


def form_valid(self, form):
    #not sure what to put here


#model_edit.py
<body>
    <form action="" method="post">{% csrf_token %}
        <table>
            <thead>
                <tr>
                    <th>Amount</th>
            </thead>
            <tbody>
                {% for i in '12345'|make_list %}
                <tr>
                    <td>
                        {{form.custom_field}}
                    </td>
                </tr>
                {% endfor %}
            </tbody>
        </table>
    </form>
</body>

【问题讨论】:

    标签: django django-forms


    【解决方案1】:

    如果要在数据传递到表单之间访问数据,可以重写ModelViewPOST方法。我假设您已尝试覆盖def form_valid,但此方法在表单验证成功后立即调用(已经在清理数据之后,在保存之前)。

    您应该能够通过覆盖ModelView 上的def post(request, *args, **kwargs) 方法直接访问POST 请求中的数据。

    另一种可能的解决方案是覆盖您已经尝试过的表单的__init__ 方法。实现这一点的方法是在调用 super().__init__(*args, *kwargs) 之前放置修改数据的代码。

        def __init__(self, *args, **kwargs):
    
            # ! <-- BEFORE super()
            # Here should be the form data accessible in the **kwargs dict.
            # by modifying data in the kwargs and later passing them to the 
            # super() you can alter the data before cleaning it in form.
    
            super().__init__(*args, **kwargs)
    
            # ! <-- AFTER super() [not here] I've tried to access the input fields here without success
    

    【讨论】:

      【解决方案2】:

      谢谢,@kryštof-Řeháček。你的回答让我走上了正轨。我能够通过更新 post 方法来实现我的目标(更改 init 不起作用)。见以下代码:

      #views.py    
      class ModelView(UpdateView):
          model = Model
          form_class = UpdateModelForm
          template_name = 'model_edit.html'
      
          def post(self, request, *args, **kwargs):
              self.object = self.get_object()
              request.POST = request.POST.copy()
              data = dict(request.POST.lists())
              custom_field = str(data['custom_field'])
              request.POST['processed_custom_field'] = custom_field
              return super().post(request, *args, **kwargs)
      

      【讨论】:

        猜你喜欢
        • 2012-12-11
        • 2015-06-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-08-21
        相关资源
        最近更新 更多