首页 > 解决方案 > 在 django rest 框架中为多种类型的用户处理一个用户模型

问题描述

我正在尝试在我的项目中使用 django rest 框架构建多类型用户 api 我有两种类型的用户: - 个人用户的客户 - 公司的公司

我想要实现的是在管理 apnel 上有两个单独的用户,在端点上有自己的视图集,但是对于 django 公司和个人用户是用户,所以当我在 json django 中显示我的个人用户端点时,会为客户和公司呈现信息,但是我在 json 中只想要一个是客户信息,而不是两者,这对于企业端点来说是同一个问题

这是我的模型:

from django.db import models
from django.contrib.auth.models import AbstractUser
from django.utils.translation import ugettext_lazy as _
from django.conf import settings


class User(AbstractUser):
    username = models.CharField(blank=True, null=True, max_length=10)
    email = models.EmailField(_('email address'), unique=True)

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['username']

    def __str__(self):
        return "{}".format(self.email)


class PersonProfile(models.Model):
    user = models.OneToOneField(settings.AUTH_USER_MODEL, 
                 on_delete=models.CASCADE, related_name='profile')
    nom = models.CharField(blank=True, null=True, max_length=50)
    photo = models.ImageField(upload_to='uploads', blank=True)
    dob = models.DateTimeField(auto_now_add=True)
    address = models.CharField(blank=True, null=True, max_length=255)
    contact_1 = models.CharField(blank=True, null=True, max_length=50)
    contact_2 = models.CharField(blank=True, null=True, max_length=50)
    country = models.CharField(blank=True, null=True, max_length=50)
    city = models.CharField(blank=True, null=True, max_length=50)


class CorporateUserProfile(PersonProfile):
    # profile = models.ForeignKey(PersonProfile)
    representant_legal = models.CharField(blank=True, null=True, 
               max_length=50)
    statut = models.CharField(blank=True, null=True, max_length=50)



class IndividualUserProfile(PersonProfile):
    prenom = models.CharField(blank=True, null=True, max_length=50)

    #class Meta:
    #    db_table = 'individual_user'

这是我的serializers.py:

from rest_framework import serializers
from api.models import User, PersonProfile, CorporateUserProfile, 
                 IndividualUserProfile

class UserProfileSerializer(serializers.ModelSerializer):
    class Meta:
        # model = PersonProfile
        model = CorporateUserProfile
        fields = ('nom', 'photo', 'dob', 'address', 'contact_1', 
                            'contact_2', 'country', 'city',
                  'representant_legal', 'statut')


class UserSerializer(serializers.HyperlinkedModelSerializer):
    profile = UserProfileSerializer(required=True)

    class Meta:
        model = User
        fields = ('url', 'email', 'password', 'profile')
        extra_kwargs = {'password': {'write_only': True}}

    def create(self, validated_data):
        profile_data = validated_data.pop('profile')
        password = validated_data.pop('password')
        user = User(**validated_data)
        user.set_password(password)
        user.save()
        CorporateUserProfile.objects.create(user=user, **profile_data)
        return user

    def update(self, instance, validated_data):
        profile_data = validated_data.pop('profile')
        profile = instance.profile

        instance.email = validated_data.get('email', instance.email)
        instance.save()
        profile.nom = profile_data.get('nom', profile.nom)
        profile.photo = profile_data.get('photo', profile.photo)
        profile.dob = profile_data.get('dob', profile.dob)
        profile.address = profile_data.get('address', profile.address)
        profile.contact_1 = profile_data.get('contact_1', profile.contact_1)
        profile.contact_2 = profile_data.get('contact_2', profile.contact_2)
        profile.country = profile_data.get('country', profile.country)
        profile.city = profile_data.get('city', profile.city)
        profile.representant_legal = profile_data.get('representant_legal', profile.representant_legal)
        profile.statut = profile_data.get('statut', profile.statut)
        profile.save()

        return instance





class IndividualUserProfileSerializer(serializers.ModelSerializer):
    class Meta:
        # model = PersonProfile
        model = IndividualUserProfile
        fields = ('nom', 'prenom', 'photo', 'dob', 'address', 'contact_1', 'contact_2', 'country', 'city')


class IndividualSerializer(serializers.HyperlinkedModelSerializer):
    profile = IndividualUserProfileSerializer(required=True)

    class Meta:
        model = User
        fields = ('url', 'email', 'password', 'profile')
        extra_kwargs = {'password': {'write_only': True}}

    def create(self, validated_data):
        profile_data = validated_data.pop('profile')
        password = validated_data.pop('password')
        user = User(**validated_data)
        user.set_password(password)
        user.save()
        IndividualUserProfile.objects.create(user=user, **profile_data)
        return user

    def update(self, instance, validated_data):
        profile_data = validated_data.pop('profile')
        profile = instance.profile

        instance.email = validated_data.get('email', instance.email)
        instance.save()
        profile.nom = profile_data.get('nom', profile.nom)
        profile.prenom = profile_data.get('nom', profile.prenom)
        profile.photo = profile_data.get('photo', profile.photo)
        profile.dob = profile_data.get('dob', profile.dob)
        profile.address = profile_data.get('address', profile.address)
        profile.contact_1 = profile_data.get('contact_1', profile.contact_1)
        profile.contact_2 = profile_data.get('contact_2', profile.contact_2)
        profile.country = profile_data.get('country', profile.country)
        profile.city = profile_data.get('city', profile.city)
        profile.save()

        return instance

这是我的views.py:

from rest_framework import viewsets
from rest_framework.permissions import AllowAny

from api.models import User
from api.serializers import UserSerializer, IndividualSerializer
# Also add these imports
from api.permissions import IsLoggedInUserOrAdmin, IsAdminUser


class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer

    # Add this code block
    def get_permissions(self):
        permission_classes = []
        if self.action == 'create':
            permission_classes = [AllowAny]
        elif self.action == 'retrieve' or self.action == 'update' or self.action == 'partial_update':
            permission_classes = [IsLoggedInUserOrAdmin]
        elif self.action == 'list' or self.action == 'destroy':
            permission_classes = [IsAdminUser]
        return [permission() for permission in permission_classes]




class IndividualViewSet(viewsets.ModelViewSet):
    # queryset = User.objects.all()
    queryset = User.objects.all()
    serializer_class = IndividualSerializer

    # Add this code block
    def get_permissions(self):
        permission_classes = []
        if self.action == 'create':
            permission_classes = [AllowAny]
        elif self.action == 'retrieve' or self.action == 'update' or self.action == 'partial_update':
            permission_classes = [IsLoggedInUserOrAdmin]
        elif self.action == 'list' or self.action == 'destroy':
            permission_classes = [IsAdminUser]
        return [permission() for permission in permission_classes]

我在个人用户的端点上拥有的是同一 json 中个人用户和公司的列表出了什么问题?:

# Create your tests here.

HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

[
    {
        "url": "http://127.0.0.1:8000/api/users/1/",
        "email": "vend@gmail.com",
        "profile": null
    },
    {
        "url": "http://127.0.0.1:8000/api/users/2/",
        "email": "vendeur@gmail.com",
        "profile": {
            "nom": "noname",
            "prenom": null,
            "photo": null,
            "dob": null,
            "address": "BP 137 Yaounde rue1037",
            "contact_1": "+237 668982566",
            "contact_2": "+237 668982569",
            "country": "Cameroun",
            "city": "Yaounde"
        }
    },
    {
        "url": "http://127.0.0.1:8000/api/users/3/",
        "email": "georges@gmail.com",
        "profile": {
            "nom": "noname",
            "prenom": null,
            "photo": null,
            "dob": null,
            "address": "BP 137 Douala rue 1137",
            "contact_1": "+237 668982567",
            "contact_2": "+237 668982570",
            "country": "Cameroun",
            "city": "Douala"
        }
    },
    {
        "url": "http://127.0.0.1:8000/api/users/4/",
        "email": "jeiffey@gmail.com",
        "profile": {
            "nom": "noname",
            "prenom": null,
            "photo": null,
            "dob": null,
            "address": "BP 137 Bafoussam rue 1134",
            "contact_1": "+237 668982568",
            "contact_2": "+237 668982571",
            "country": "Cameroun",
            "city": "Bafoussam"
        }
    },
    {
        "url": "http://127.0.0.1:8000/api/users/5/",
        "email": "degrasguemto@gmail.com",
        "profile": {
            "nom": "noname",
            "prenom": null,
            "photo": "http://127.0.0.1:8000/api/users/uploads/963840d34c51efe6fbe57749fb434646.jpg",
            "dob": "2019-09-22T13:46:23.682584Z",
            "address": "BP 137 Yaounde rue 5024",
            "contact_1": "+237 691679613",
            "contact_2": "+237 678590793",
            "country": "Cameroun",
            "city": "Yaounde"
        }
    },
    {
        "url": "http://127.0.0.1:8000/api/users/6/",
        "email": "gdegras@gmail.com",
        "profile": {
            "nom": "degras",
            "prenom": null,
            "photo": "http://127.0.0.1:8000/api/users/uploads/Lamp-3D-Wallpaper-photos-images_VcIDh6z.jpg",
            "dob": "2019-09-22T22:23:08.271455Z",
            "address": "BP 3306 Yaounde rue 1137",
            "contact_1": "+237 691679613",
            "contact_2": "+237 678590793",
            "country": "Cameroun",
            "city": "Yaounde"
        }
    },
    {
        "url": "http://127.0.0.1:8000/api/users/7/",
        "email": "IUTFV@gmail.com",
        "profile": {
            "nom": "IUT FV",
            "prenom": null,
            "photo": null,
            "dob": "2019-09-22T22:25:22.702443Z",
            "address": "BP 137 Bafoussam rue 1134",
            "contact_1": "+237 668982566",
            "contact_2": "+237 668982569",
            "country": "Cameroun",
            "city": "Yaounde"
        }
    }
]

标签: django

解决方案


推荐阅读