我正在尝试动态生成模型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如何找到模型的字段?
答案 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')