jul*_*ria 6 python django foreign-keys
假设我有这两个模型:
class Distribution(models.Model):
name = models.CharField(max_length=32)
class Component(models.Model):
distribution = models.ForeignKey(Distribution)
percentage = models.IntegerField()
Run Code Online (Sandbox Code Playgroud)
我正在使用一个简单的在管理表单中TabularInline显示Components Distribution:
class ComponentInline(admin.TabularInline):
model = Component
extra = 1
class DistributionAdmin(admin.ModelAdmin):
inlines = [ComponentInline]
Run Code Online (Sandbox Code Playgroud)
因此,我的目标是在保存之前验证总和100 的所有Components 的百分比Distribution.听起来很简单,所以我做了:
# ... Inside the Distribution model
def clean(self):
# Sum of components must be 100
total_sum = sum(comp.percentage for comp in self.component_set.all())
if total_sum != 100:
raise ValidationError('Sum of components must be 100%')
Run Code Online (Sandbox Code Playgroud)
但是这永远不会起作用,因为在Django中所有对象都在保存其外键或许多相关对象之前保存,这不是一个缺陷,它有一个原因:它不能先保存相关对象,因为它们对象是有关没有一个id定义,但(id是None直到对象保存在数据库第一次).
我敢肯定我不是第一个遇到这个问题的人.那么,有没有办法完成我想要做的事情?我想也许是管理员黑客使用TabularInline或ModelAdmin......?
如果您愿意将验证从模型移动到内联表单集,那么这是一个(未经测试的)想法:
子类化BaseInlineFormSet并重写 clean 方法以检查百分比总和。
from django.forms.models import BaseInlineFormSet
from django.core.exceptions import ValidationError
class ComponentInlineFormSet(BaseInlineFormSet):
def clean(self):
"""Check that sum of components is 100%"""
if any(self.errors):
# Don't bother validating the formset unless each form is valid on its own
return
total_sum = sum(form.cleaned_data['percentage'] for form in self.forms)
if total_sum != 100:
raise ValidationError('Sum of components must be 100%')
Run Code Online (Sandbox Code Playgroud)
然后在ComponentInline.
class ComponentInline(admin.TabularInline):
model = Component
extra = 1
formset = ComponentInlineFormSet
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
947 次 |
| 最近记录: |