【问题标题】:Dynamic Instance Specific Django Field Creation动态实例特定的 Django 字段创建
【发布时间】:2019-03-02 20:01:01
【问题描述】:

我有一种情况,用户模型可以有“X”个需要添加的唯一字段。这些字段需要对它们运行查询,所以我不能只添加一个包含 JSON 字符串的字段。例如,一位用户可能看起来像:

class User(models.Model):
    name = models.CharField()
    age = models.IntegerField()
    sex = models.CharField()
    profession = models.CharField()

下一个可能是:

class User(models.Model):
    name = models.CharField()
    age = models.IntegerField()
    sex = models.CharField()
    badge_number = models.IntegerField()

就像我上面所说的,这些唯一字段必须是可查询的。救命!!

【问题讨论】:

    标签: python mysql django django-models


    【解决方案1】:

    如果您的意思不是 Django/DB 意义上的唯一性,您可以尝试使用 postgres JSONField,这是一个存储 JSON 且可查询的字段。

    文档中的示例代码:

    from django.contrib.postgres.fields import JSONField
    from django.db import models
    
    class Dog(models.Model):
        name = models.CharField(max_length=200)
        data = JSONField()
    
        def __str__(self):
            return self.name
    

    以及查询:

    >>> Dog.objects.create(name='Rufus', data={
    ...     'breed': 'labrador',
    ...     'owner': {
    ...         'name': 'Bob',
    ...         'other_pets': [{
    ...             'name': 'Fishy',
    ...         }],
    ...     },
    ... })
    >>> Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': None})
    
    >>> Dog.objects.filter(data__breed='collie')
    <QuerySet [<Dog: Meg>]>
    

    【讨论】:

      【解决方案2】:

      从您的问题中不清楚这些是否完全是任意的“可能存在这些字段的任何组合”,是否存在使可能的组合更易于处理的子集,或者甚至是否完整的可能字段集甚至是预定义的,但您可能至少有以下选项之一。

      1. 编写一个包含所有可能字段的单个用户类(或用户配置文件类),其中的字段可能在一个用户上但不是另一个用户设置为null=True
      2. 拥有多种用户类型,使用不同的字段扩展 User(或其超类之一)。
      3. 在查询单个用户模型时,编写一个自定义管理器以(昂贵地)解压 JSON 或其他多值字段,以从查询中手动删除您的自定义字段并将它们应用于初步结果集。
      4. 将用户配置文件模型链接到您的用户类,然后对其进行子类化以添加可能字段的各种组合。

      继承可以将这种情况变成真正的痛苦,所以我会避免这种情况......对于你描述的情况,我认为#1可能是最合适的。如果您的用例不接受 null=True,您的选项就会变得不那么可口、可读性和可维护性降低。

      注意:@henriquesalvaro 的答案是在我写这篇文章时出现的,并且似乎优于以下选项。无论如何我都会发布这个,以防 JSONField 不是你可以使用的东西。

      【讨论】:

        猜你喜欢
        • 2020-03-18
        • 1970-01-01
        • 2011-02-20
        • 2011-08-26
        • 2021-12-26
        • 1970-01-01
        • 2015-02-09
        • 2011-04-12
        • 1970-01-01
        相关资源
        最近更新 更多