Django管理界面:覆盖内联初始值

4

我的一个模型有一个默认值字段,我很满意,但是我希望在管理页面中这个默认值不同。以下是我的尝试:

models.py

from django.db import models


class Parent(models.Model):
    parent_field_1 = models.CharField(max_length=255)
    parent_field_2 = models.CharField(max_length=255, blank=True)

    class Meta:
        ordering = ('pk',)

    def __unicode__(self):
        return self.parent_field_1


class Child(models.Model):
    parent = models.ForeignKey(Parent)
    child_field_1 = models.CharField(max_length=255)
    child_field_2 = models.CharField(max_length=255, blank=True)
    child_field_3 = models.IntegerField(default=0)

    class Meta:
        ordering = ('pk',)
        verbose_name_plural = 'children'

    def __unicode__(self):
        return self.child_field_1

forms.py

from django import forms

from .models import Child


class ChildForm(forms.ModelForm):
    class Meta:
        model = Child
        fields = [
            'parent',
            'child_field_1',
            'child_field_2',
            'child_field_3',
        ]

    def __init__(self, *args, **kwargs):
        if 'instance' not in kwargs:
            initial = kwargs.get('initial', {})
            initial['child_field_3'] = '1'
            kwargs['initial'] = initial

        super(ChildForm, self).__init__(*args, **kwargs)

admin.py

from django.contrib import admin

from .forms import ChildForm
from .models import Parent, Child


class ChildInline(admin.StackedInline):
    model = Child
    form = ChildForm


class ParentAdmin(admin.ModelAdmin):
    inlines = [ChildInline]


class ChildAdmin(admin.ModelAdmin):
    form = ChildForm

admin.site.register(Parent, ParentAdmin)
admin.site.register(Child, ChildAdmin)

当我在添加子项时,“Child field 3”字段填充了“1”(而不是模型的默认值“0”),这正是我想要的。当我去编辑子项时,“Child field 3”字段被填充了数据库中的任何值,这也是我想要的。
但是,当我尝试添加或编辑父项时遇到了问题。如果我尝试添加父项,则必须填写所有子表单。同样,如果我尝试编辑父项,则必须填写所有额外的子表单。如果我注释掉“ChildInline”类的“form = ChildForm”行,则可以获得正确的行为,但是默认值将变成“0”而不是“1”。如何同时获得正确的行为和正确的默认值?
1个回答

2

您的字段是一个IntegerField。您必须将initial设置为整数。

当表单允许为空(这里的情况),如果表单没有更改,则full_clean忽略has_changed()changed_data的空值确定。

字段更改由field.has_changed(initial, data)确定,其中数据通过field.to_python(value)传递,对于IntegerField,它返回一个整数。另一方面,initial应该是正确类型的并且保持不变。这导致比较:has_changed = ('1' != 1),返回True,而您期望它返回False


使用self.fields['child_field_3'].initial = '1'代替我的代码并没有产生任何区别。使用您的调试代码,以下内容被输出了三次:(['child_field_3'], True) - Nick
哇,就是这样!谢谢!我的逻辑最初是从网上某个地方复制/粘贴的。不知怎么的,我认为初始值总是应该是字符串,但显然并非如此。再次感谢! - Nick

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接