django inline_formset - 根据另一个字段

时间:2018-04-07 14:41:50

标签: django inline-formset

我有三个模型 - Item,Invoice和InvoiceItem。每个项目可能有一个或多个与之关联的税组(名称,费率等)。

class Item(models.Model):
    name=models.CharField(max_length=100, unique=True, db_index=True)
    tax_group=models.ManyToManyField(TaxGroup)

class Invoice(models.Model):
    number=models.CharField("invoice number",max_length=20,unique=True,default=invoiceIncrement,  )
    date=models.DateField("invoice date")
    contact=models.ForeignKey(Contact, on_delete=models.CASCADE)
    total=models.DecimalField(decimal_places=2, max_digits=12)

class InvoiceItem(models.Model):
    invoice=models.ForeignKey(Invoice, on_delete=models.CASCADE, related_name='invoice_items')
    item=models.ForeignKey(Item, on_delete=models.CASCADE)
    tax=models.ForeignKey(TaxGroup, on_delete=models.CASCADE)
    quantity=models.PositiveIntegerField()
    rate=models.DecimalField(decimal_places=2, max_digits=12)
    total=models.DecimalField(decimal_places=2, max_digits=12,null=True)

我使用下面的表格制作了一个inline_formset,如下所示。

class InvoiceItemForm(forms.ModelForm):
    class Meta:
        model=InvoiceItem
        exclude=()
ItemInlineFormSet = inlineformset_factory(Invoice, 
    InvoiceItem, form=InvoiceItemForm, 
    extra=1, can_delete=False,
      validate_min=True, min_num=1)

现在,我需要确保对应于表单集中每个所选项目,字段 tax 应仅包含与其关联的税。

对于客户端,我有添加了一些ajax 代码,以根据每个项目字段的选择填充税字段。

如何确保所选税字段是Item对象的ManyToMany值之一?

我尝试指定一个自定义formset 来为字段设置 queryset ,例如

class BaseItemFormSet(forms.BaseInlineFormSet):
    def __init__(self, *args, **kwargs):
        super(BaseItemFormSet, self).__init__(*args, **kwargs)

        for form in self.forms:
            form.fields['tax'].queryset = Item.objects.get(form.fields['item']).tax_group.all()

这不起作用(我不确定这是否是正确的方法)。

我是否需要在formset中使用clean()方法来验证每个字段?

请帮忙,

感谢。

2 个答案:

答案 0 :(得分:0)

是(后端)验证,您需要对InvoiceItemForm上的税区进行自定义验证:

class InvoiceItemForm(forms.ModelForm):

    def clean_tax(self):
        selected_tax_group = self.cleaned_data['tax']
        # your custom validation (TaxGroup lookup and validation)
        is_valid_tax_group = False
        if not is_valid_tax_group
            raise forms.ValidationError("Invalid Tax Group selected")

        return data

    class Meta:
        model=InvoiceItem
        exclude=()

我希望有所帮助!

答案 1 :(得分:0)

这是我的表现。

branch.<name>.remote

(欢迎可能的简化)