0

我有一个与其他 3 个模型相关的 Django 模型(ChildrenGodfather):Child、Godfather 和 Edition(2012、2013、2014 ..)。

当我们创建一个新的 ChildrenGodfather 时,没有 Edition 字段:它使用最新版本自动保存它,而不向用户显示它(已经工作)

我们不能在同一个版本中拥有相同的孩子和相同的教父,但我们可以在不同的版本中拥有相同的孩子和相同的教父。

问题是..创建时表单中没有字段版本,所以我们没有办法验证版本。所以我们的验证是不允许我们在不同的版本中拥有同一个教父的 Child。

你可以在这里得到一个工作代码:

==== 模型.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']

谢谢。

4

2 回答 2

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)     
于 2013-09-10T15:30:19.837 回答
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']

如果您希望 Edition 字段在对象创建时隐藏,但在对象版本中可见,您可以将此方法添加到您的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
于 2013-09-10T15:31:42.173 回答