django - 带有动态字段的 django rest 框架中的序列化程序

标签 django django-rest-framework

我正在尝试使用 django rest 框架构建一个小 api,但我不想直接映射带有调用的表(如示例中所示)。

我有以下数据库架构:

在models.py中:

class ProductType(models.Model):
    name = models.CharField(max_length=255, blank=False, null=False, unique=True)


class Product(models.Model):
    @staticmethod
    def get_accepted_fields(self):
        return {'color': 'pink', 'size': 34, 'speed': 0, 'another_prop': ''} 

    name = models.CharField(max_length=255, blank=False, null=False, unique=True)


class ProductConfig(models.Model):
    product_type = models.ForeignKey(ProductType)
    product = models.ForeignKey(Product)

    # a json field with all kind of fields: eg: {"price": 123, "color": "red"}
    value = models.TextField(blank=True)

如您所见,每个产品都可以有多种配置,而 value 字段是具有不同参数的 json。 json 将只有一个级别。配置将有一个标志是否处于事件状态(因此,1 个产品将只有 1 个事件配置)

因此,数据将如下所示:
store_producttype
=================
1   type1
2   type2

store_product
=============
id  name    
1   car 


store_productconfig
===================
id  product_type_id     product_id  value                                       active
1   2           1       {  "color": "red",  "size": 34,  "speed": 342}                  0
2   1           1       {  "color": "blue",  "size": 36,  "speed": 123, "another_prop": "xxx"}      1

我想知道的是我怎样才能得到这样的/product/1/:
{
    "id": 1,
    "name": "car",
    "type": "type1",
    "color": "blue",
    "size": 36,
    "speed": 123,
    "another_prop": "xxx",

}

并创建一个新产品,发布一个与上面类似的 json。
json 字段已定义,但其中一些字段可能会丢失(例如:productconfig.id=1 中的“another_prop”

无论如何,在更新时,它会在 productconfig 中创建一个新行,并将 inactive=0 放在前一行上。

所以,每个产品都可以有不同的配置,我想在某些特定情况下回到特定的配置)。我并没有真正受制于这个数据模型,所以如果你有改进的建议,我对他们持开放态度,但我不想将这些属性作为表中的列。

问题是,为此模型编写序列化程序的最佳方法是什么?对于这样的用例,某处有什么好的例子吗?

谢谢你。

最佳答案

让我们一步一步来:

  • 为了获得像您发布的那样的 JSON,您必须首先将您的字符串(productConfig 值字段)转换为字典。这可以通过使用 ast.literal_eval 来完成。 (查看更多 here)。

  • 然后,在您的产品序列化程序中,您必须为每个字段指定源,如下所示:
    class ProductSerializer(serializers.ModelSerializer):
        color = serializer.Field(source='value_dict.color')    
        size = serializer.Field(source='value_dict.size')
        type = serializer.Field(source='type.name')
    
    class Meta:
        model = Product
        fields = (
            'id',
            'color',
            'size',
            'type',
        )
    

    这应该可以很好地创建您想要的表示。但是,这不会自动创建产品配置,因为 DRF 还不允许创建嵌套对象。
    这使我们进入下一步:
  • 要使用来自 JSON 的配置创建产品,您必须覆盖 View 中的 post 方法,并自己创建它。这部分不应该那么难,但如果你需要一个例子,就问吧。
  • 这更多是一个建议:如果 json 字段已经定义,在 productConfig 模型中将它们定义为单独的字段不是更容易吗?
  • 关于django - 带有动态字段的 django rest 框架中的序列化程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25080617/

    相关文章:

    python - Django - 将变量从函数 View 传递到 html 模板

    python - Django 事务 ATOMIC_REQUESTS

    django - 如何获取自定义超链接字段以包含额外的 url 变量并适用于所有 ModelViewSet?

    具有 2 个或更多字段的 Django 序列化程序方法字段

    jquery - Django查询慢,优化

    python - 如何在 django Rest 框架中发出具有数组属性的对象的 POST 请求

    python - DRF 不适用于鹡鸰

    django - 如何限制用户对自己的模型进行投票

    python - Django - 多个数据库

    python - Django 找不到应用程序模板