我有一个Django模型(ChildrenGodfather),涉及其他3个模型:Child,Godfather和Edition(2012,2013,2014 ..)。
当我们创建一个新的ChildrenGodfather时,没有Edition字段:它会自动使用最新版本保存它,而不会向用户显示(已经工作)
我们不能在同一版本中拥有相同教父的同一个孩子,但我们可以在不同的版本中拥有相同教父的同一个孩子。
问题是..创建时表单中没有字段版本,所以我们没有办法验证版本。所以我们的验证不允许我们在不同的版本中让Child与同一个教父。
您可以在此处获得有效的代码:
==== models.py ====
class Edition(models.Model):
name = models.CharField(max_length=255, verbose_name=u'Name')
date = models.DateField(verbose_name=u'Date')
class Godfather(models.Model):
name = models.CharField(max_length=255, verbose_name=u'Name')
is_active = models.BooleanField(_('active'), default=True, help_text=u'Is active?')
class Children(models.Model):
name = models.CharField(max_length=255, verbose_name=u'Name')
is_active = models.BooleanField(_('active'), default=True, help_text=u'Is active?')
class ChildrenGodfather(models.Model):
class Meta:
verbose_name = u'Sponsorship'
unique_together = ['child', 'godfather', 'edition']
child = models.ForeignKey(Children, verbose_name=u'Child')
godfather = models.ForeignKey(Godfather, verbose_name=u'Godfather')
edition = models.ForeignKey(Edition)
def save(self, *args, **kwargs):
# if it is creating, don t need to tell edition
if not self.pk:
self.edition = Edition.objects.order_by('-date')[0:1].get()
super(ChildrenGodfather, self).save(*args, **kwargs)
==== forms.py ====
class ChildrenGodfatherForm(forms.ModelForm):
child = forms.ModelChoiceField(label=u'Child', queryset=Children.objects.filter(is_active=True))
godfather = forms.ModelChoiceField(label=u'Godfather', queryset=Godfather.objects.filter(is_active=True))
# TODO improve checking for editions
def clean(self):
try:
ChildrenGodfather.objects.get(child=self.cleaned_data['child'],
godfather=self.cleaned_data['godfather'])
#if we get this far, we have an exact match for this form's data
raise forms.ValidationError(u"This sponsorship already exists. Duplicated sponsorship are not allowed!")
except ChildrenGodfather.DoesNotExist:
#because we didn't get a match
pass
return self.cleaned_data
==== admin.py ====
class ChildrenGodfatherAdmin(admin.ModelAdmin):
form = ChildrenGodfatherForm
fields = ['child', 'godfather']
list_display = ['__unicode__', 'child', 'godfather', 'status']
list_filter = ['child', 'godfather', 'status']
感谢。
答案 0 :(得分:1)
您可以覆盖ChildrenGodfatherForm的 init 方法来初始化默认版
def __init__(self, *args, **kwargs):
super(ChildrenGodfatherForm, self).__init__(*args,**kwargs)
instance = kwargs.get('instance')
if instance is not None:
self.edition = instance.edition # updating existing object, use its edition
else:
self.edition = Edition.objects.latest('date') # creating new object, use default edition.
然后在clean方法中修改查询以使用此参数
ChildrenGodfather.objects.get(child=self.cleaned_data['child'],
godfather=self.cleaned_data['godfather'], edition=self.edition)
答案 1 :(得分:1)
def default_edition():
return Edition.objects.latest('date') # or Edition.objects.order_by('-date')[0]
class ChildrenGodfather(models.Model):
class Meta:
verbose_name = u'Sponsorship'
unique_together = ['child', 'godfather', 'edition']
child = models.ForeignKey(Children, verbose_name=u'Child')
godfather = models.ForeignKey(Godfather, verbose_name=u'Godfather')
edition = models.ForeignKey(Edition, default=default_edition)
def save(self, *args, **kwargs):
super(ChildrenGodfather, self).save(*args, **kwargs)
class ChildrenGodfatherAdmin(admin.ModelAdmin):
form = ChildrenGodfatherForm
fields = ['child', 'godfather', 'edition']
list_display = ['__unicode__', 'child', 'godfather', 'edition', 'status']
list_filter = ['child', 'godfather', 'edition', 'status']
如果您希望在创建对象时隐藏版本字段,但在对象版本上可见,则可以将此方法添加到ChildrenGodfatherAdmin
类:
def get_form(self, request, obj=None, **kwargs):
if obj is None:
self.exclude = ["edition"]
form = super(ChildrenGodfatherAdmin, self).get_form(request, obj, **kwargs)
return form