django中的序列化器使用动态字段来休息框架

时间:2014-08-01 12:45:17

标签: 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)

如您所见,每个产品都可以有多个配置,值字段是具有不同参数的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字段已定义,但其中一些可能会遗漏(例如:" another_prop"在productconfig.id = 1

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

因此,每个产品都可以有不同的配置,我想在某些特定情况下及时回到特定配置。我并不是真的受这个数据模型的束缚,所以如果你有改进的建议我会对他们开放,但我不想把这些属性作为表中的列。

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

谢谢。

1 个答案:

答案 0 :(得分:0)

让我们一步一步:

  1. 为了获得与您发布的JSON类似的JSON,您必须先将字符串(productConfig值字段)转换为字典。这可以通过ast.literal_eval来完成(请参阅更多here)。
  2. 然后,在产品序列化程序中,您必须为每个字段指定源,如下所示:

    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尚不允许嵌套对象创建。 这导致我们进入下一步:

    1. 要使用JSON配置创建产品,您必须在视图中覆盖 post 方法,并自行创建。这部分不应该那么难,但如果你需要一个例子,那就问问。

    2. 这是一个更多的建议:如果已经定义了json字段,那么在productConfig模型中将它们定义为单独的字段会不会更容易?