【问题标题】:Django form inheritance with Crispy Forms带有 Crispy Forms 的 Django 表单继承
【发布时间】:2021-01-08 01:07:04
【问题描述】:

我正在尝试以更 DRY 的方式处理 Django 中的表单。我正在使用 Django Crispy Forms 来布置和呈现表单。

我有一个模型:

class Txn(models.Model): 
    transaction_date = models.DateField()
    reference = models.CharField(max_length=12)
    arrived = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True)
    used = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True)
    sent= models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True)
    adjust = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True)

对于 4 个数字字段(到达、使用、发送、调整)中的每一个,我都有一个仅公开其中一个字段的表单。 (顺便说一句,这是基于从另一个项目继承的模型 - 我知道有更好的方法来构建它,但我必须使用这个结构)。因此,我创建了 4 个看起来非常相似的表单:

class TxnUseForm(forms.ModelForm):
    class Meta:
        model = Txn
        fields = ('transaction_date', 'reference', 'used') 

    def __init__(self, *args, **kwargs):
        super(TxnUseForm, self).__init__(*args, **kwargs)

        # Layout definition for the form
        self.helper = FormHelper()
        self.helper.form_tag = False
        self.helper.layout = Layout(
            Row(
                Column(Field('reference', autocomplete="off", autofocus="autofocus"), css_class='form-group col-sm-4 mb-0 pb-0'),
                Column(Field('transaction_date'), css_class='form-group col-sm-4 mb-0 pb-0'),
                Column(Field('used', step='1'), css_class='form-group col-sm-4 mb-0 pb-0')
            )
        )

    # Validation for amount used - must be a positive number
    def clean_used(self):
        data = self.cleaned_data['used']
        if data is None or data == "":
            data=0
        if data <=0:
            raise forms.ValidationError("Must be a positive number.")
        return data

其他 3 个表单称为 TxnArrivedForm、TxnAdjustForm 和 TxnSentForm,它们与 TxnUsedForm 完全相同 - 表单的唯一区别是公开的数字字段。我正在尝试对表单进行子类化并使用继承来减少代码。我尝试了以下方法:

class TxnBaseForm(forms.ModelForm):
    class Meta:
        model = Txn
        fields = ('transaction_date', 'reference')

    def __init__(self, *args, **kwargs):
        super(TxnBaseForm, self).__init__(*args, **kwargs)

        # Layout definition for the form
        self.helper = FormHelper()
        self.helper.form_tag = False
        self.helper.layout = Layout(
            Row(
                Column(Field('transaction_date'), css_class='form-group col-sm-4 mb-0 pb-0'),
                Column(Field('reference',  autocomplete="off", autofocus="autofocus"), css_class='form-group col-sm-4 mb-0 pb-0'),
            )
        )

class TxnUseForm(TxnBaseForm):
    class Meta(TxnBaseForm.Meta):
        fields = TxnBaseForm.Meta.fields + ('used',)
       
    def __init__(self, *args, **kwargs):
        super(TxnUseForm, self).__init__(*args, **kwargs)
        self.helper.layout.append =  Column(Field('used',step='1'), css_class='form-group col-sm-4 mb-0 pb-0')
        self.fields['used'].label = "Qty. Used"

    # Validation for amount used - must be a positive number
    def clean_used(self):
        data = self.cleaned_data['used']
        if data is None:
            data=0
        if data <=0:
            raise forms.ValidationError("Must be a positive number.")
        return data

交易日期和参考字段显示,但使用的字段根本没有得到呈现。我做错了什么或错过了什么?

跟进:由于我们还不知道该字段的名称,是否有一种简单的方法来处理基本表单中该字段的验证?

感谢您的任何反馈!

【问题讨论】:

    标签: django django-forms django-crispy-forms


    【解决方案1】:

    你的代码有错误。

    self.helper.layout.append = Column(Field('used',step='1'), css_class='form-group col-sm-4 mb-0 pb-0')

    应该是:

    self.helper.layout.append(Column(Field('used',step='1'), css_class='form-group col-sm-4 mb-0 pb-0'))

    【讨论】:

      猜你喜欢
      • 2022-01-04
      • 2016-12-20
      • 2019-12-31
      • 2020-04-06
      • 2014-12-21
      • 1970-01-01
      • 2014-02-22
      • 2015-05-13
      • 2017-02-02
      相关资源
      最近更新 更多