django inline_formset - 为基于另一个字段的字段设置查询集
django inline_formset - set queryset for a field based on another field
我有三个模型 - 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 值之一?
我已经尝试指定一个自定义表单集来为字段设置一个查询集,比如
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()
这行不通(而且我不确定这是否是正确的方法)。
我是否需要在表单集中使用 clean() 方法来验证每个字段?
请帮忙,
谢谢。
是 (back-end) 验证您需要对 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=()
希望对您有所帮助!
这是我的做法。
def __init__(self, *args, **kwargs):
super(InvoiceItemFormSet, self).__init__(*args, **kwargs)
if self.data:
i=0
for form in self.forms:
key = 'item-'+str(i)+'-item'
if self.data[key]:
form.fields['tax'].queryset= Item.objects.get(id=self.data[key]).tax_group.all()
i=i+1
(欢迎进行可能的简化)
我有三个模型 - 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 值之一?
我已经尝试指定一个自定义表单集来为字段设置一个查询集,比如
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()
这行不通(而且我不确定这是否是正确的方法)。
我是否需要在表单集中使用 clean() 方法来验证每个字段?
请帮忙,
谢谢。
是 (back-end) 验证您需要对 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=()
希望对您有所帮助!
这是我的做法。
def __init__(self, *args, **kwargs):
super(InvoiceItemFormSet, self).__init__(*args, **kwargs)
if self.data:
i=0
for form in self.forms:
key = 'item-'+str(i)+'-item'
if self.data[key]:
form.fields['tax'].queryset= Item.objects.get(id=self.data[key]).tax_group.all()
i=i+1
(欢迎进行可能的简化)