[英]Django: allow user to add fields to model
I am just starting with Django and want to create a model for an application.我刚开始使用 Django,想为应用程序创建模型。
I find Djangos feature to - automatically define validations and html widget types for forms according to the field type defined in the model and - define a choice set for the field right in the model very usefull and I want to make best use of it.我发现 Django 的功能可以 - 根据模型中定义的字段类型自动定义表单的验证和 html 小部件类型,并且 - 为模型中的字段定义一个选择集非常有用,我想充分利用它。 Also, I want to make best use of the admin interface.
另外,我想充分利用管理界面。
However, what if I want to allow the user of the application to add fields to the model?但是,如果我想允许应用程序的用户向模型添加字段怎么办? For example, consider a simple adress book.
例如,考虑一个简单的通讯录。 I want the user to be able to define additional atributes for all of his contacts in the admin settings, ie add a fax number field, so that a fax number can be added to all contacts.
我希望用户能够在管理设置中为他的所有联系人定义其他属性,即添加传真号码字段,以便可以将传真号码添加到所有联系人。
from a relational DB perspective, I would have a table with atributes (PK: atr_ID, atr_name, atr_type) and an N:N relation between atributes and contacts with foreign keys from atributes and contacts - ie it would result in 3 tables in the DB.从关系数据库的角度来看,我将有一个带有属性的表(PK:atr_ID、atr_name、atr_type)以及属性和联系人之间的 N:N 关系以及来自属性和联系人的外键 - 即它会在数据库中生成 3 个表. right?
对?
but that way I cannot define the field types directly in the Django model.但那样我就不能直接在 Django 模型中定义字段类型。 Now what is best practice here?
现在这里的最佳实践是什么? How can I make use of Djangos functionality AND allow the user to add aditional/custom fields via the admin interface?
如何利用 Django 的功能并允许用户通过管理界面添加附加/自定义字段?
Thank you!谢谢! :)
:)
Best Teconomix最佳 Teconomix
i would suggest storing json as a string in the database, that way it can be as extendable as you want and the field list can go very long.我建议将 json 作为字符串存储在数据库中,这样它就可以根据需要进行扩展,并且字段列表可以很长。
Edit: If you are using other damn backends you can use Django-jsonfield.编辑:如果您使用其他该死的后端,您可以使用 Django-jsonfield。 If you are using Postgres then it has a native jsonfield support for enhanced querying, etc.
如果您使用的是 Postgres,那么它具有用于增强查询等的本机 jsonfield 支持。
Edit 2: Using django mongodb connector can also help.编辑 2:使用 django mongodb 连接器也有帮助。
I've used this approach, first seen in django-payslip , to allow for extendable fields.我已经使用了这种方法,首先在django-payslip 中看到,以允许可扩展的字段。 This provides a structure for adding fields to models, from which you can allow users to add/edit through standard view procedures (no admin hacking necessary).
这提供了向模型添加字段的结构,您可以从中允许用户通过标准视图程序添加/编辑(无需管理黑客)。 This should be enough to get you started, and taking a look at django-payslip's source code (see the views) also provides view Mixins and forms as an example of how to render to users.
这应该足以让您入门,查看 django-payslip 的源代码(请参阅视图)还提供了视图 Mixins 和表单作为如何呈现给用户的示例。
class YourModel(models.Model):
extra_fields = models.ManyToManyField(
'your_app.ExtraField',
verbose_name=_('Extra fields'),
blank=True, null=True,
)
class ExtraFieldType(models.Model):
"""
Model to create custom information holders.
:name: Name of the attribute.
:description: Description of the attribute.
:model: Can be set in order to allow the use of only one model.
:fixed_values: Can transform related exta fields into choices.
"""
name = models.CharField(
max_length=100,
verbose_name=_('Name'),
)
description = models.CharField(
max_length=100,
blank=True, null=True,
verbose_name=_('Description'),
)
model = models.CharField(
max_length=10,
choices=(
('YourModel', 'YourModel'),
('AnotherModel', 'AnotherModel'), # which models do you want to add extra fields to?
),
verbose_name=_('Model'),
blank=True, null=True,
)
fixed_values = models.BooleanField(
default=False,
verbose_name=_('Fixed values'),
)
class Meta:
ordering = ['name', ]
def __unicode__(self):
return '{0}'.format(self.name)
class ExtraField(models.Model):
"""
Model to create custom fields.
:field_type: Connection to the field type.
:value: Current value of this extra field.
"""
field_type = models.ForeignKey(
'your_app.ExtraFieldType',
verbose_name=_('Field type'),
related_name='extra_fields',
help_text=_('Only field types with fixed values can be chosen to add'
' global values.'),
)
value = models.CharField(
max_length=200,
verbose_name=_('Value'),
)
class Meta:
ordering = ['field_type__name', ]
def __unicode__(self):
return '{0} ({1}) - {2}'.format(
self.field_type, self.field_type.get_model_display() or 'general',
self.value)
You can use InlineModelAdmin objects.您可以使用InlineModelAdmin对象。 It should be something like:
它应该是这样的:
#models.py
from django.db import models
class Person(models.Model):
name = models.CharField(max_length=100)
class ContactType(models.Model):
name = models.CharField(max_length=100)
class Contact(models.Model):
person = models.ForeignKey(Person, on_delete=models.CASCADE)
contact_type = models.ForeignKey(ContactType, on_delete=models.CASCADE)
value = models.CharField(max_length=100)
#admin.py
from django.contrib import admin
class ContactInline(admin.TabularInline):
model = Contact
class PersonAdmin(admin.ModelAdmin):
inlines = [
ContactInline,
]
By the way... stackoverflow questions should contain some code.顺便说一句... stackoverflow 问题应该包含一些代码。 You should try to do something before asking a question.
在提出问题之前,您应该尝试做一些事情。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.