如何在Django序列化程序SlugRelatedField

时间:2018-12-31 12:04:06

标签: python django serialization django-rest-framework

我有两个模型ProductTypeModel和ProductModel,product_type是产品中的外键。然后,我为产品编写了ModelSerializer,以获取ProductModel的所有条目以及一些其他信息。 现在,我无法从ProductSerializer中的ProductTypeModel获取product_sub_type

我在序列化程序中尝试过SlugRelatedField,试图设置slug_field=product_sub_typeslug_field=product_type__product_sub_typeslug_field=product_type.product_sub_type

models.py

class ProductType(models.Model):
    """Product type model."""

    id = models.UUIDField(
        primary_key=True, 
        default=uuid.uuid4,
        editable=False
    )
    hsn = models.ForeignKey(
        HSN, 
        related_name='product_types',
        on_delete=models.SET_NULL, 
        null=True, blank=True
    )
    product_type = models.CharField(max_length=255, null=True, blank=True)
    product_sub_type = models.CharField(max_length=255, db_index=True)
    description = models.CharField(max_length=255, null=True, blank=True)  

    def __str__(self):
        return str(self.product_type)

    def get_sub_type(self):
        return str(self.product_sub_type)

    class Meta:
        db_table = 'ProductTypes'
        unique_together = ('product_type', 'product_sub_type')


class Product(models.Model):
    """Products model."""

    product_id = models.UUIDField(
        primary_key=True, 
        default=uuid.uuid4,
        editable=False
    )
    product_type = models.ForeignKey(
        ProductType, 
        related_name='related_products',
        on_delete=models.SET_NULL, 
        blank=True, null=True
    )
    name = models.CharField(max_length=255, db_index=True)
    code_name = models.CharField(max_length=255, null=True, blank=True)
    href = models.CharField(max_length=500, blank=True, null=True)
    full_name = models.CharField(max_length=255, null=True, blank=True, db_index=True)
    manufacturer = models.ForeignKey(
        Manufacturer, 
        related_name='manufactured_products', 
        on_delete=models.SET_NULL,
        null=True, blank=True
    )
    packing = models.CharField(max_length=255, null=True, blank=True)
    packing_detail = models.CharField(max_length=255, null=True, blank=True)
    mrp = models.DecimalField(
        max_digits=8, 
        decimal_places=2, 
        null=True, blank=True
    )
    created_at = models.DateTimeField(
        'created at', 
        db_index=True, 
        default=timezone.now
    )

    def __str__(self):
        return str(self.full_name)

    class Meta:
        db_table = 'Products'
        unique_together = ('code_name', 'product_type')

serializers.py

class ProductTypeSerializer(serializers.ModelSerializer):
    # Serialize/Deserialize ProductType instance.

    class Meta:
        model = ProductType
        fields = (
            'id', 'hsn', 
            'product_type', 'product_sub_type', 
            'description'
        )
        read_only_fields = ('id', )


class ProductSerializer(serializers.ModelSerializer):
    # Serialize/Deserialize Product instance.

    manufacturer = serializers.StringRelatedField()
    manufacturer_id = serializers.PrimaryKeyRelatedField(read_only=True)
    product_sub_type = serializers.SlugRelatedField(slug_field=????)

    class Meta:
        model = Product
        fields = (
            'product_id', 
            'product_type', 'product_sub_type', 
            'name', 'code_name',
            'manufacturer', 'manufacturer_id', 
            'full_name', 
            'packing', 'packing_detail', 
            'mrp'
        )
        read_only_fields = (
            'product_id', 'created_at', 
            'product_type', 'manufacturer_id'
        )

使用slug_field=product_sub_type返回 ImproperlyConfigured at /products/ Field name product_sub_type is not valid for model Product.

使用slug_field=product_type.product_sub_type返回 AttributeError at /products/ Got AttributeError when attempting to get a value for field product_sub_type on serializer ProductSerializer.The serializer field might be named incorrectly and not match any attribute or key on the Product instance.

我希望序列化程序返回如下内容:

{
    "count": 1,
    "next": null,
    "previous": null,
    "results": [
        {
            "product_id": "fffcf7ba-5c6d-4190-96d2-cc9125e18e71",
            "product_type": "1b3dd955-b67e-4ca3-9561-6d1704ff7c91",
            "product_sub_type": "Capsules",
            "name": "Enshine Toothpaste",
            "code_name": null,
            "manufacturer": "Leeford Healthcare Ltd",
            "manufacturer_id": 2524,
            "full_name": "Enshine Toothpaste",
            "packing": null,
            "packing_detail": null,
            "mrp": null
        }
    ]
}

1 个答案:

答案 0 :(得分:0)

提供属性slug_fieldsource适用于只读SlugRelatedField。要允许在此字段中写入,还必须提供queryset属性

class ProductSerializer(serializers.ModelSerializer):
    ...
    product_sub_type = serializers.SlugRelatedField(
        slug_field='product_sub_type',
        source='product_type',
        queryset=ProductType.objects.all()
    )

根据documentation slug_field应该是一个唯一标识任何给定实例的字段

相关问题