Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
django rest框架中带有动态字段的序列化程序_Django_Django Rest Framework - Fatal编程技术网

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

django rest框架中带有动态字段的序列化程序,django,django-rest-framework,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_acc

我试图用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
{
    "id": 1,
    "name": "car",
    "type": "type1",
    "color": "blue",
    "size": 36,
    "speed": 123,
    "another_prop": "xxx",

}
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',
    )
我想知道的是我怎样才能得到这样的/product/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
{
    "id": 1,
    "name": "car",
    "type": "type1",
    "color": "blue",
    "size": 36,
    "speed": 123,
    "another_prop": "xxx",

}
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',
    )
并创建一个新产品,发布一个与上面类似的json。 json字段已定义,但其中一些字段可能会丢失(例如productconfig.id=1中的“另一个_prop”)

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

因此,每个产品都可以有不同的配置,我想在某些特定情况下回到特定的配置)。我并没有真正绑定到这个数据模型,所以如果您有改进建议,我愿意接受它们,但我不希望将这些属性作为表中的列

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


谢谢。

让我们一步一步来:

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

    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
    
    {
        "id": 1,
        "name": "car",
        "type": "type1",
        "color": "blue",
        "size": 36,
        "speed": 123,
        "another_prop": "xxx",
    
    }
    
    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的配置创建产品,必须在视图中重写post方法,然后自己创建。这一部分不应该太难,但是如果你需要一个例子,尽管问

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


  • 谢谢你的建议。我也不想手动将所有属性(颜色、大小、速度等)添加到ProductSerializer中,并再次添加到字段中,因为可以是10、20。。。100个属性,我还不知道,其中一些是可选的。可以根据Product.get\u accepted\u fields()或productconfig.value(json)中的get(如果是get)动态创建它们吗?谢谢。恐怕没有办法做到这一点。因为颜色、大小等不是模型上的实际字段,所以必须在序列化程序中将它们声明为字段。否则,DRF将不知道如何映射到值。