【问题标题】:Django: how store multiple data types to the same model fieldDjango:如何将多种数据类型存储到同一个模型字段
【发布时间】:2022-01-04 17:47:07
【问题描述】:

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

这个想法是用户(或任何模型)可以具有多个具有不同值的不同特征(或其他)。特征可以是任何东西,例如整数(薪水)、日期(生日)或多项选择(C、Python 等能力)。为了保持数据库设计简单,我尝试了一种方法,我只有一个 Feature 表,它通过 Choice 表具有可选选项,而不是为每种特征类型设置单独的数据库表。用户对特征值的选择存储到 User_has_Feature 表的“值”字段中,该字段是一个 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.

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

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

【问题讨论】:

    标签: django django-models django-admin


    【解决方案1】:

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

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

    更新:

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

    1. 对关系用户功能使用多对多。您可以在用户模型中将此字段定义为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)
    
        ...
    

    【讨论】:

    • 我试图避免为所有功能创建专用类。即使使用这种方法,它也无法解决 value 字段的问题,因为 value 存储在链接模型中而不是特征模型中。
    • 您可以为功能创建父类和子类。如果该功能有自己的实现 - 它看起来像不同的类。对于您的第二个陈述 - 我没有明白 - 您可以使用链接实例及其值。只需覆盖 getter。
    • 我不明白你的意思,也许提供一个例子。我可以为每个功能设置不同的类,但唯一的区别是字段类型,无论是整数、日期、多选等,我已经将这些信息存储在字段表中。如果我为所有这些创建自己的类,那么我仍然有同样的问题,我如何在链接“User_has_Feature”类的“值”字段中处理多种数据类型。不想去一个方向,我还需要为每个特征类型提供自己的链接模型,只是为了更改“值”的字段类型。
    • 好的,如果您不想为功能创建不同的类,我已经更新了另一种方法。
    • 这种管理方法不起作用,“db_field.name”只是一个“值”,但值/字段的类型在管理中不可用。我可以考虑为特性创建不同的类,但它不能解决主要问题,即必须在链接模型中为特定用户分配特定值的“值”字段,并且“值”可以是不同的类型取决于它链接到的功能。
    猜你喜欢
    • 2017-09-20
    • 2023-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-20
    • 1970-01-01
    • 2019-02-22
    • 2019-10-02
    相关资源
    最近更新 更多