当前位置: 代码迷 >> python >> 在使用序列化程序时,反向关系如何在Django模型中工作?
  详细解决方案

在使用序列化程序时,反向关系如何在Django模型中工作?

热度:76   发布时间:2023-07-14 08:59:39.0

这是我的models.py

from __future__ import unicode_literals
from django.db import models
from pygments.lexers import get_all_lexers
from pygments.styles import get_all_styles
from pygments.lexers import get_lexer_by_name
from pygments.formatters.html import HtmlFormatter
from pygments import highlight


LEXERS = [item for item in get_all_lexers() if item[1]]
LANGUAGE_CHOICES = sorted([(item[1][0], item[0]) for item in LEXERS])
STYLE_CHOICES = sorted((item, item) for item in get_all_styles())


class Snippet(models.Model):
    created = models.DateTimeField(auto_now_add=True)
    title = models.CharField(max_length=100, blank=True, default='')
    code = models.TextField()
    linenos = models.BooleanField(default=False)
    language = models.CharField(choices=LANGUAGE_CHOICES, default='python', max_length=100)
    style = models.CharField(choices=STYLE_CHOICES, default='friendly', max_length=100)
    owner = models.ForeignKey('User')

    class Meta:
        ordering = ('created',)

    def __str__(self):
        return self.title

class User(models.Model):
    name = models.CharField(max_length=100, blank=True, default='')
    def __str__(self):
        return self.name

这是我的seralizers.py

from rest_framework import routers, serializers, viewsets
from .models import Snippet
from django.contrib.auth.models import User
from rest_framework import permissions
class SnippetSerializer(serializers.ModelSerializer):
    owner = serializers.ReadOnlyField(source='owner.user')
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,)

    class Meta:
        model = Snippet
        fields = '__all__'

class UserSerializer(serializers.ModelSerializer):
    snippets = serializers.PrimaryKeyRelatedField(many=True, queryset=Snippet.objects.all())

    class Meta:
        model = User
        fields = '__all__'

这是我的view.py

from __future__ import unicode_literals

from django.shortcuts import render
from django.http import HttpResponse, JsonResponse

from .models import *
from .serializers import *
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status,mixins,generics
from django.http import Http404


class SnippetList(generics.ListCreateAPIView):
    queryset = Snippet.objects.all()
    serializer_class = SnippetSerializer

    def perform_create(self, serializer):
        serializer.save(owner=self.request.user)


class SnippetDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Snippet.objects.all()
    serializer_class = SnippetSerializer

class UserList(generics.ListCreateAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer


class UserDetail(generics.RetrieveAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer

这是我的urls.py

from django.conf.urls import url, include
from django.contrib import admin
from rest_framework.urlpatterns import format_suffix_patterns
from api.models import *
from api import views
from api.serializers import UserSerializer


urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^snippets/$', views.SnippetList.as_view()),
    url(r'^snippets/(?P<pk>[0-9]+)/$', views.SnippetDetail.as_view()),
    url(r'^users/$', views.UserList.as_view()),
    url(r'^users/(?P<pk>[0-9]+)/$', views.UserDetail.as_view()),
    url(r'^api-auth/', include('rest_framework.urls')),
]
urlpatterns = format_suffix_patterns(urlpatterns)

我想在摘要中获取所有者名称,因为它在Snippet模型中被定义为外键,并且再次要求获得用户中所有摘要的详细信息。

预期的摘要应该像这样

[
    {
        "id": 1,
        "created": "2018-09-23T06:05:15.416966Z",
        "title": "hello code",
        "code": "print -< \"hello\"",
        "linenos": false,
        "language": "python",
        "style": "friendly",
        "owner": "soubhagya"
    }
]

预期的用户应该是这样的

    [
        {
            "name":"soubhagya",
            "snippets": [
                "id": 1,
                "created": "2018-09-23T06:05:15.416966Z",
                "title": "hello code",
                "code": "print -< \"hello\"",
                "linenos": false,
                "language": "python",
                "style": "friendly",
            ]
        }
    ]

如何根据这两个样本获取数据。

您为关系使用了错误的序列化程序。 您阅读过吗? 这是一个非常好的介绍,并向您显示了您需要的两个领域:

  • 代码段中用户名的 。
  • 用户片段的

您的用户模型已经具有正确的__str__方法,返回self.name ,因此您应该使此工作非常容易。

但是,请勿对嵌套的嵌套代码使用SnippetSerializer,因为它将再次将所有者放入其中。 而是编写不包含所有者字段的第二个序列化器。 工作正常后,将公共字段重构并放在一个串行器上,然后通过扩展它将所有者字段添加到第二个串行器中,以使其保持DRY状态。