Py学习  »  Django

django rest嵌套序列化程序中扩展用户配置文件更新问题

Md. Mahmudul Islam • 4 年前 • 246 次点击  


我正在关注django rest文档 https://www.django-rest-framework.org/api-guide/relations/#writable-nested-serializers

我的序列化程序.py

from django.contrib.auth.models import User
from rest_framework import serializers
from accounts.models import Profile, Address, Contact, Religious, Contact, Gender
from rest_framework.response import Response


class AddressSerializer(serializers.ModelSerializer):
    class Meta:
        model = Address
        fields = [
            "village",
            "postoffice",
            "postcode",
            "upazila",
            "district",
            "city",
            "state",
            "country",
        ]


class ReligiousSerializer(serializers.ModelSerializer):
    class Meta:
        model = Religious
        fields = ["religious"]


class GenderSerializer(serializers.ModelSerializer):
    class Meta:
        model = Gender
        fields = ["gender"]


class ContactSerializer(serializers.ModelSerializer):
    class Meta:
        model = Contact
        fields = [
            "phone",
            "social_link",
        ]


class ProfileSerializer(serializers.ModelSerializer):
    class Meta:
        model = Profile
        fields = [
            "birth_date",
        ]


class AccountSerializer(serializers.ModelSerializer):
    profile = ProfileSerializer(required=False, allow_null=True)
    address = AddressSerializer(required=False, allow_null=True)
    gender = GenderSerializer(required=False, allow_null=True)
    religious = ReligiousSerializer(required=False, allow_null=True)
    contact = ContactSerializer(required=False, allow_null=True)

    class Meta:
        model = User
        fields = [
            "id",
            "username",
            "email",
            "password",
            "first_name",
            "last_name",
            "profile",
            "address",
            "gender",
            "religious",
            "contact",
        ]
        extra_kwargs = {
            "username": {"required": True},
            "email": {"required": True},
            "password": {"required": True},
        }
        read_only_fields = ("username", "email")
        # write_only_fields = ("password",)
        # username no updatable

    def update(self, instance, validated_data):

        profile_data = validated_data.pop("profile")
        address_data = validated_data.pop("address")
        gender_data = validated_data.pop("gender")
        religious_data = validated_data.pop("religious")
        contact_data = validated_data.pop("contact")

        profile = instance.profile

        address = instance.address

        gender = instance.gender

        religious = instance.religious

        contact = instance.contact

        """
        Update and return an existing `User` instance, given the validated data.
        """
        instance.username = validated_data.get("username", instance.username)
        instance.email = validated_data.get("email", instance.email)
        # updated password hashed
        password = validated_data.get("password", None)
        instance.set_password(password)
        instance.save()

        profile.save()
        address.save()
        gender.save()
        religious.save()
        contact.save()

        return instance

视图.py

from django.shortcuts import render
from django.conf import settings

from django.contrib.auth.models import User
from accounts.serializers import AccountSerializer
from rest_framework.authentication import TokenAuthentication
from rest_framework import mixins
from rest_framework import generics
from rest_framework import permissions
from rest_framework.permissions import (
    AllowAny,
    IsAuthenticated,
    IsAdminUser,
    IsAuthenticatedOrReadOnly,
)
from permissions.permissions import IsOwnerOrReadOnly




class AccountList(
    mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView
):
    queryset = User.objects.all()
    serializer_class = AccountSerializer
    authentication_classes = (TokenAuthentication,)
    permission_classes = [
        IsAuthenticated,
        IsOwnerOrReadOnly,
    ]

    def get_queryset(self):
        """
        Filter data of devices that belongs to user who made the request.
        """
        return User.objects.all().filter(username=self.request.user)

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

    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)



class AccountDetail(
    mixins.RetrieveModelMixin,
    mixins.UpdateModelMixin,
    mixins.DestroyModelMixin,
    generics.GenericAPIView,
):
    queryset = User.objects.all()
    serializer_class = AccountSerializer
    authentication_classes = (TokenAuthentication,)
    permission_classes = [
        IsAuthenticated,
        IsOwnerOrReadOnly,
    ]

    def get_queryset(self):
        """
        Filter data of devices that belongs to user who made the request.
        """
        return User.objects.all().filter(username=self.request.user)

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

    def get(self, request, *args, **kwargs):
        return self.retrieve(request, *args, **kwargs)

    def put(self, request, *args, **kwargs):
        return self.update(request, *args, **kwargs)

    def delete(self, request, *args, **kwargs):
        return self.destroy(request, *args, **kwargs)

模型.py

from django.db import models
from django.contrib.auth.models import User
from django.core.validators import RegexValidator
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
birth_date = models.DateField(null=True, blank=True)
class Address(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
village = models.CharField(max_length=200, null=True, blank=True)
postoffice = models.CharField(max_length=200, null=True, blank=True)
postcode = models.CharField(max_length=200, null=True, blank=True)
upazila = models.CharField(max_length=200, null=True, blank=True)
district = models.CharField(max_length=200, null=True, blank=True)
city = models.CharField(max_length=200, null=True, blank=True)
state = models.CharField(max_length=200, null=True, blank=True)
country = models.CharField(max_length=200, null=True, blank=True)
class Religious(models.Model):
RELIGIOUS_CHOICES = (
("I", "Islam"),
("C", "Christianity"),
("H", "Hinduism"),
("B", "Buddhism"),
("O", "Other"),
)
user = models.OneToOneField(User, on_delete=models.CASCADE)
religious = models.CharField(
max_length=1, choices=RELIGIOUS_CHOICES, null=True, blank=True
)
class Gender(models.Model):
GENDER_CHOICES = (
("M", "Male"),
("F", "Female"),
("O", "Other"),
)
user = models.OneToOneField(User, on_delete=models.CASCADE)
gender = models.CharField(
max_length=1, choices=GENDER_CHOICES, null=True, blank=True
)
class Contact(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
phone_regex = RegexValidator(
regex=r"^\+?1?\d{3,11}$",
message="Phone must be entered in the format: '+880'. Up 11 digits allowed.",
)
phone = models.CharField(
validators=[phone_regex], max_length=11, null=True, blank=True
)
social_link = models.TextField(null=True, blank=True)
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/56802
 
246 次点击