Django:如何将多种数据类型存储到同一模型字段

m5s*_*pal 5 django django-models django-admin

我想创建一个类似于下面示例的数据库模型:

在此输入图像描述

这个想法是用户(或任何模型)可以具有多个具有不同值的不同特征(或其他特征)。特征可以是任何内容,例如整数(工资)、日期(生日)或多项选择(C、Python 等能力)。为了保持数据库设计简单,我尝试了一种方法,其中只有一个功能表,该表通过选择表提供可选选择,而不是为每种功能类型设置单独的数据库表。用户对特征值的选择存储到 User_has_Feature 表的“value”字段中,该字段是一个 CharField,可以存储多种不同的数据类型,如整数、日期、选择、多项选择等。

我的问题是,如何验证所有数据,以便它根据字段数据类型进行验证,并在管理或 UI 中正确显示所有内容(针对不同类型具有不同的 UI 小部件)?

我尝试了一种方法,将每个功能的字段类型存储到字段表中,可以是 CharField、IntegerField、DateField 等。然后在 User_has_Feature 模型 clean() 中,我可以动态验证字段类型,例如:

FIELDS = {
    'DateField': DateField,
    'IntegerField': IntegerField,
    etc.
}

def clean(self):
    class_ = FIELDS.get(self.feature.field)
    if class_ in [DateField, IntegerField, ...]:
        field = class_()
        field.clean(self.value)
    elif class_ in [ModelChoiceField, ModelMultipleChoiceField]:
        etc.
Run Code Online (Sandbox Code Playgroud)

这种方法对于验证来说效果很好,但它对管理小部件没有帮助,而且数据总是作为字符串处理,而不是整数、日期、列表等。所以我开始研究创建自定义 ValueField 模型的选项field,它继承 CharField,并将所有数据作为字符串存储到数据库中,但会动态更改值的小部件和数据类型 (to_python)。到目前为止还没有成功,我尝试的一切似乎都过于复杂。

对我来说,这似乎是相当普遍的需求,因此我希望已经存在一些“简单”的解决方案。或者然后我需要尝试完全不同的数据库设计方法。

fan*_*nni 0

您可以使用 Django 内容类型框架文档

主要思想是您可以为您的功能创建专用的类(模型),并且 CTF 可以帮助您将功能链接到用户(在您的情况下)。我使用它来将不同的模型链接到日志记录模型,并且每个日志记录实例都包含指向其记录的所需模型实例的直接链接。

更新:

好的,用 Django 术语来说,我们需要:

  1. 将 ManyToMany 用于关系 User<->Features。features您可以像在用户模型中一样定义该字段。所以以后的调用会很简单,比如:user.features.all()。管理相关功能也将变得简单。
  2. 您的clean方法是正确的:您正在将字段的 str 类型的字符串名称映射到类。没关系。
  3. 使用此技巧可以在管理员端表单上进行相同的映射
class OurModelAdmin(admin.ModelAdmin):
    
    ...

    def formfield_for_dbfield(self, db_field, **kwargs):
        
        if db_field.name == 'Multiple':
            kwargs['widget'] = forms.CheckboxSelectMultiple
        
        # mapping is here

        return super(OurModelAdmin, self).formfield_for_dbfield(db_field,**kwargs)

    ...
Run Code Online (Sandbox Code Playgroud)