django:动态创建的模型mixin的字段不会出现在ModelForm中

时间:2014-02-26 20:55:17

标签: django

我正在尝试动态生成模型mixin。

我在使用ModelForm时看到字段时遇到问题,但是字段存在 在最终的模型中。

def create_address_fields_mixin(prefix='', fields_kwargs={}):

    class AddressFieldsModelMixin(models.Model):
        class Meta:
            abstract = True

    fields = {
        'address_line_1': (AddressLineModelField, {'editable': True}),
        'address_line_2': (AddressLineModelField, {'blank':True, 'null':True}),
        'city': (CityModelField, {}),
        'state': (USStateModelField, {}),
        'zipcode': (USZipCodeModelField, {})
    }

    for field_name, (field_klass, kwargs) in fields.iteritems():

        name = '{}{}'.format(prefix, field_name)
        kwargs.update( fields_kwargs.get(field_name, {}) )

        setattr(
            AddressFieldsModelMixin,
            name,
            field_klass(**kwargs)
        )

    return AddressFieldsModelMixin


AddressModelMixin = create_address_fields_mixin(prefix='main_')

class User(AddressModelMixin, TimeStampedModel):
    pass

创建模型并访问字段工作:

u = User()
u.main_address_line_1 # works

但是当使用ModelForm时,字段似乎不存在:

class UserForm(ModelForm):    
    class Meta:
        model = User

f = UserForm()
f.fields # the fields from the model mixin do not exist

ModelForm如何找到模型的字段?

2 个答案:

答案 0 :(得分:0)

我想你应该总是在{4}}中明确地列出模型中的字段。

所以这可能会有所帮助:

class UserForm(ModelForm):    
    class Meta:
        model = User
        fields = '__all__'

答案 1 :(得分:0)

好的,我找到了解决方案。 问题是我动态创建模型的方式。这些字段并未真正添加到模型中。

以下是解决方案,以便它可以帮助遇到相同问题的人:

def create_model_mixin(model_name, model_base, model_definition, fields_prefix='', fields_kwargs={}):
     # Build the class attributes
    attrs = {}
    attrs['__module__'] = __name__

    # Create the relevant meta information
    class Meta:
        abstract = True

    attrs['Meta'] = Meta

    # Build the model by adding django database Field subclasses to the attrs dict
    for field_name, field_klass, kwargs in model_definition['fields']:
        name = '{}{}'.format(fields_prefix, field_name)
        kwargs.update( fields_kwargs.get(field_name, {}) )
        attrs[name] = field_klass(**kwargs)

    # Create the new model class
    model_class = type(model_name, (model_base,), attrs)

    return model_class

你可以这样使用它:

model_name = 'AddressModelMixin'
model_base = models.Model
model_definition = {
    'fields': [
        ('address_line_1', AddressLineModelField, {}),
        ('address_line_2', AddressLineModelField, {'blank':True, 'null':True}),
        ('city', CityModelField, {}),
        ('state', USStateModelField, {}),
        ('zipcode', USZipCodeModelField, {})
    ]
}

model_class = create_model_mixin(model_name, model_base, model_definition, fields_prefix='my_prefix')