Python Django REST:通过UUID进行序列化程序查找

Python Django REST:通过UUID进行序列化程序查找,python,django,django-models,django-rest-framework,Python,Django,Django Models,Django Rest Framework,我正在Django REST中创建这个简单的购物API 在内部,我使用id作为外键约束,而guuid则被带到外部世界 对于签出过程,用户提供他愿意购买的物品ID列表。因此,POST数据中的对象如下所示: { assets: [ { 'product': 'd9d5044d-2284-4d15-aa76-2eee3675035b', 'amount': 4 }, .... ] } # Asset serializer class Ass

我正在Django REST中创建这个简单的购物API

在内部,我使用id作为外键约束,而
guuid
则被带到外部世界

对于签出过程,用户提供他愿意购买的物品ID列表。因此,POST数据中的对象如下所示:

{
  assets: [
    {
       'product': 'd9d5044d-2284-4d15-aa76-2eee3675035b',
       'amount': 4
    },
    ....
  ]
}
# Asset serializer
class AssetSerializer(serializers.ModelSerializer):

    class Meta:
        model = Asset
        fields = ('stock_item', 'amount')


# Ticket serializer
class TicketSerializer(WritableNestedModelSerializer):
    owner = serializers.ReadOnlyField(source='owner.username')
    assets = AssetSerializer(many=True)

    class Meta:
        model = Ticket
        fields = ('uuid', 'owner', 'assets', )

    def perform_create(self, serializer):
        serializer.save(owner=self.request.user)
我正在使用以下票据/资产模型:

# Ticket
class Ticket(models.Model):
    uuid = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)
    owner = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='tickets', on_delete=models.CASCADE)


# Assets
class Asset(models.Model):
    ticket = models.ForeignKey(Ticket, related_name='assets', on_delete=models.CASCADE)
    stock_item = models.ForeignKey(Stock, related_name='stock_item', on_delete=models.SET_NULL, null=True)
    amount = models.IntegerField(validators=[MinValueValidator(0)])
序列化程序如下所示:

{
  assets: [
    {
       'product': 'd9d5044d-2284-4d15-aa76-2eee3675035b',
       'amount': 4
    },
    ....
  ]
}
# Asset serializer
class AssetSerializer(serializers.ModelSerializer):

    class Meta:
        model = Asset
        fields = ('stock_item', 'amount')


# Ticket serializer
class TicketSerializer(WritableNestedModelSerializer):
    owner = serializers.ReadOnlyField(source='owner.username')
    assets = AssetSerializer(many=True)

    class Meta:
        model = Ticket
        fields = ('uuid', 'owner', 'assets', )

    def perform_create(self, serializer):
        serializer.save(owner=self.request.user)
过帐上述指定类型的对象时,会出现以下错误:

{"assets":[{"stock_item": ["Invalid type. Expected PK, received string"]}]}
我似乎无法解决这个问题,如何指示序列化程序使用
uuid
作为查找值?我之前通过使用
lookup\u字段
成员解决了视图级别的类似问题,但这似乎并没有解决它。有什么建议吗?

在此处输入代码

如果我理解正确,a应该能够找到正确的相关对象

class AssetSerializer(serializers.ModelSerializer):
票证=序列化程序。SlugRelatedField(
只读=真,
slug_field='uuid',
queryset=Ticket.objects.all()#可能与read_only=True冗余
)
类元:
模型=资产
字段=('ticket'、'stock\u item'、'amount')

< />代码>您知道在Sulk中,SulgRelieldFieldSerialSerialServer在读取时返回紧凑的十六进制表示,而不是用中间的破折号返回那个讨厌的东西吗?BjornW我不太清楚你说的“紧凑十六进制表示法”是什么意思。如果你不想要slug字段,你可能应该使用slug字段以外的其他字段。据我所知(和stackoverflow),如果你想在PrimaryKey以外的其他字段上创建相关字段,没有其他明智的选择可以替代PrimaryKeyRelatedField。我认为这是一个很大的限制。因此,通常建议使用SlugField,但它的缺点是不能像PrimaryKeyRelatedField那样逐个指定字段(例如,pk_字段可以设置为UUIDField(format='hex'),但slug_字段只是一个字符串)。回答你的问题:UUID的紧凑十六进制有时看起来比API中的虚线默认值要好。作为其他有相同问题的人的参考。我只是对SlugRelatedField进行了子分类,并为to_表示添加了一个覆盖,返回getattr(obj,self.slug_field).hex