简体   繁体   English

Django REST POST用PK到HyperlinkedModelSerializer,如何将PK翻译成URL?

[英]Django REST POST with PK to HyperlinkedModelSerializer, how to translate PK to URL?

I'm new to Django and Django REST. 我是Django和Django REST的新手。 I have been creating a simple practice project. 我一直在创建一个简单的练习项目。

Models: 楷模:

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)

Serializers: 串行器:

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')

Views: 浏览次数:

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

I use this to POST: 我用它来POST:

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

But then the response is 但后来回应是

"locker_owner": [ "This field is required." “locker_owner”:[“此字段是必填字段。” ] ]

Main Point: I would like to create a new locker , and use User id as its locker_owner, yet still maintain the HyperlinkedModelSerializer . 要点我想创建一个新的储物柜 ,并使用用户ID作为其locker_owner,但仍然维护HyperlinkedModelSerializer It won't let me, since they need url for locker_owner. 它不会让我,因为他们需要url for locker_owner。 Once I use hyperlink in the locker_owner of my POST request it works, but I don't know how to translate locker_owner=2 to it's url. 一旦我在我的POST请求的locker_owner中使用超链接就可以了,但是我不知道如何将locker_owner = 2翻译成它的url。

Any help would be appreciated. 任何帮助,将不胜感激。 I have been looking for answers in days. 我一直在寻找答案。 Thank you! 谢谢!

This is not something you can do out-of-the-box. 这不是你可以开箱即用的东西。 You will need to implement your own custom serializer Field, and override the to_representation method: 您需要实现自己的自定义serializer字段,并覆盖to_representation方法:

serializers.py 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')

You can then simply POST a simple JSON to create a new Locker object: 然后,您可以简单地POST一个简单的JSON来创建一个新的Locker对象:

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

I have found the solution myself looking at the tutorials available. 我自己找到了可用的教程解决方案。 The other answers have not really answered the question fully. 其他答案并没有真正完全回答这个问题。

For those wanting to get url of a foreign key to be saved, here, locker_owner, just get them using hyperlinked related field 对于那些想要保存外键的url的人,这里,locker_owner,只是使用超链接相关字段获取它们

In my serializer: 在我的序列化器中:

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')

I was trying to get the id in the lookup field, but actually the lookup field is searching the id from my url. 我试图在查找字段中获取id,但实际上查找字段正在从我的url中搜索id。 That's why it could not find it. 这就是为什么它找不到它。 Simple and done. 简单而完成。 Thank you for all the answers. 谢谢你的所有答案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM