Django Rest Framework (DRF) jedan je od učinkovito napisanih okvira oko Djanga i pomaže u izgradnji REST API-ja za pozadinu aplikacije.
Koristio sam ga u jednom od svojih osobnih projekata i nabasao na ovaj izazov "serializiranja modela koji referencira drugi model putem polja OneToOne."
`Koristio sam model korisnika iz django.contrib.auth.models
. Htio sam napisati API za stvaranje i ažuriranje korisničkog objekta kroz jedan API koji također ažurira atribute mog modela. Rješenje je bilo koristiti ugniježđene odnose DRF-a u serializaciji.
Pretpostavit ću da dobro poznajete Python, virtualenv, pip, Django i DRF prije nego što nastavite. Ako ne, naučite više i slobodno se vratite ako ikad zapnete u ugniježđenim odnosima u serializaciji.
Primjer koji ovdje razmatram je model sveučilišnog studenta koji se poziva na model korisnika putem polja OneToOne. Moj je cilj jedinstveni API za stvaranje i dobivanje korisničkih podataka poput imena, korisničkog imena i e-pošte, zajedno s atributom učenika, kao što je glavni predmet.
Evo kako models.py
izgleda moj izgled:
from django.db import models from django.contrib.auth.models import User class UnivStudent(models.Model): """ A class based model for storing the records of a university student Note: A OneToOne relation is established for each student with User model. """ user = models.OneToOneField(User) subject_major = models.CharField(name="subject_major", max_length=60)
Dalje, serializator za gornji model određuje atribute kojima će se manipulirati. Ako primijetite dolje, imam 2 klase serializatora,UserSerializer
i StudentSerializer
.To je naša točka interesa.
Proglasio sam user
atribut koji je ovdje polje serializatora. Taj user
će atribut primarno sadržavati cijelu referencu za UserSerializer
klasu. U područjima u StudentSerializer
, možemo samo vidjeti „ user
” i „ subject_major
”. To nam omogućuje da unesemo atribute učenika (ili korisnika) zajedno s subject_major.
Stvara se korisnički unos na koji referencira unos učenika. Nadjačavamo metodu stvaranja da StudentSerializer
bismo user
prvo stvorili objekt i koristimo je za stvaranje student
objekta.
Slijedi serializer.py
sljedeće:
from rest_framework import serializers, status from models import * class UserSerializer(serializers.ModelSerializer): class Meta: model = User fields = ('username', 'first_name', 'last_name', 'email') class StudentSerializer(serializers.ModelSerializer): """ A student serializer to return the student details """ user = UserSerializer(required=True) class Meta: model = UnivStudent fields = ('user', 'subject_major',) def create(self, validated_data): """ Overriding the default create method of the Model serializer. :param validated_data: data containing all the details of student :return: returns a successfully created student record """ user_data = validated_data.pop('user') user = UserSerializer.create(UserSerializer(), validated_data=user_data) student, created = UnivStudent.objects.update_or_create(user=user, subject_major=validated_data.pop('subject_major')) return student
views.py
Treba prilično jednostavan, ako ste već upoznati s pogledom klase na bazi od Django. Koristit ćemo serializator za provjeru valjanosti i stvaranje objekata modela:
from serializers import * from models import * from rest_framework.views import APIView from rest_framework.response import Response from rest_framework import status class StudentRecordView(APIView): """ A class based view for creating and fetching student records """ def get(self, format=None): """ Get all the student records :param format: Format of the student records to return to :return: Returns a list of student records """ students = UnivStudent.objects.all() serializer = StudentSerializer(students, many=True) return Response(serializer.data) def post(self, request): """ Create a student record :param format: Format of the student records to return to :param request: Request object for creating student :return: Returns a student record """ serializer = StudentSerializer(data=request.data) if serializer.is_valid(raise_exception=ValueError): serializer.create(validated_data=request.data) return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.error_messages, status=status.HTTP_400_BAD_REQUEST)
Uključio sam /univstud/
url
za postizanje post
i get
zahtjeve za studente.
from django.conf.urls import patterns, include, url from django.contrib import admin from rest_framework import routers from rest_framework.urlpatterns import format_suffix_patterns from OneToOne import views admin.autodiscover() router = routers.DefaultRouter() urlpatterns = patterns('', url(r'^admin/', include(admin.site.urls)), url(r'^api-auth/', include('rest_framework.urls', namespace="rest_framework")), ) urlpatterns += format_suffix_patterns([ # API to map the student record url(r'^api/univstud/$', views.StudentRecordView.as_view(), name="students_list"), ])
Poziv POST
zahtjeva izgledao bi otprilike ovako:

Poziv Get
zahtjeva izgledao bi otprilike ovako:

To je sve!:)
Ugnježđeni odnos je tako omogućen na StudentSerializer
referenci user
.
Kompletni kôd nalazi se u mom gitlab spremištu.
Reference:
- //www.django-rest-framework.org/api-guide/relations/