【问题标题】:Django REST POST with PK to HyperlinkedModelSerializer, how to translate PK to URL?带有 PK 的 Django REST POST 到 HyperlinkedModelSerializer,如何将 PK 转换为 URL?
【发布时间】:2018-09-17 04:30:53
【问题描述】:

我是 Django 和 Django REST 的新手。我一直在创建一个简单的练习项目。

型号:

class Locker(models.Model):
    locker_owner = models.ForeignKey(User, related_name='lockers', on_delete=models.CASCADE)
    locker_desc = models.CharField(max_length=100)
    locker_rating = models.IntegerField(default=0)

序列化器:

class LockerSerializer(serializers.ModelSerializer):
    locker_owner = serializers.HyperlinkedRelatedField(
        view_name='user-detail',
        lookup_field='id',
        queryset=User.objects.all())
    # how to add locker owner with id?

class Meta:
    model = Locker
    fields = ('url', 'locker_desc', 'locker_rating', 'locker_owner')

class UserSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = User
        fields = ('url', 'id', 'username', 'email', 'groups')

观看次数:

class UserViewSet(viewsets.ModelViewSet):
    """
    API endpoint that allows users to be viewed or edited.
    """
    queryset = User.objects.all().order_by('-date_joined')
    serializer_class = UserSerializer

class LockerViewSet(viewsets.ModelViewSet):
    """
    API endpoint that allows lockers to be viewed or edited.
    """
    # def create(self, request):
    queryset = Locker.objects.all()
    serializer_class = LockerSerializer

我用这个来发帖:

ttp -f POST localhost:8000/lockers/ locker_owner_id=2 locker_desc='desc of locker 3' locker_rating=150

然后响应是

“locker_owner”:[ “这是必填栏。” ]

要点: 我想创建一个新的储物柜,并使用用户 ID 作为它的 locker_owner,但仍然维护 HyperlinkedModelSerializer .它不会让我,因为他们需要 locker_owner 的 url。一旦我在我的 POST 请求的 locker_owner 中使用超链接,它就可以工作,但我不知道如何将 locker_owner=2 翻译成它的 url。

任何帮助将不胜感激。这几天我一直在寻找答案。谢谢!

【问题讨论】:

  • 所以你需要知道如何在url中设置locker_owner=2,对吗?这个问题解决了吗?
  • 您可以停止使用 DjangoRest 并按照自己的方式行事。它将比 drf 快速且功能强大。如果你能满足于不超过api_view

标签: python django rest django-rest-framework


【解决方案1】:

这不是开箱即用的事情。您需要实现自己的自定义serializer 字段,并覆盖to_representation 方法:

serializers.py

from rest_framework.reverse import reverse


class CustomRelatedField(serializers.PrimaryKeyRelatedField):

    def to_representation(self, value):
         return reverse('<your-user-detail-view-name>', args=(value.pk,), request=self.context['request'])


class LockerSerializer(serializers.ModelSerializer):
    locker_owner = CustomRelatedField(queryset=User.objects.all())

    class Meta:
       model = Locker
       fields = ('url', 'locker_desc', 'locker_rating', 'locker_owner')

然后您可以简单地 POST 一个简单的 JSON 来创建一个新的 Locker 对象:

{
    "locker_owner": 2,
    "locker_desc": 'desc of locker 3',
    "locker_rating": 150
}

【讨论】:

    【解决方案2】:

    我自己在查看可用教程时找到了解决方案。其他答案并没有真正完全回答问题。

    对于那些想要获取要保存的外键的url,在这里,locker_owner,只需使用超链接相关字段获取它们

    在我的序列化器中:

    class LockerSerializer(serializers.HyperlinkedModelSerializer):
        locker_owner=serializers.HyperlinkedRelatedField(
            read_only=True,
            view_name='user-detail')
    
        class Meta:
            model = Locker
            fields = ('locker_desc', 'locker_rating', 'locker_owner')
    

    我试图在查找字段中获取 id,但实际上查找字段正在从我的 url 中搜索 id。这就是它找不到它的原因。简单而完成。谢谢大家的回答。

    【讨论】:

      猜你喜欢
      • 2014-07-12
      • 1970-01-01
      • 2023-04-06
      • 1970-01-01
      • 1970-01-01
      • 2021-12-20
      • 2019-05-24
      • 2013-07-07
      相关资源
      最近更新 更多