我正在尝试在DRF中实现多种用户类型,而通过
我已经为用户模型设置了身份验证和权限,现在可以登录。我希望登录的用户能够创建其各自的配置文件(基于用户模型的user_type字段)。
class User(AbstractBaseUser, PermissionsMixin):
""" A Generic User inside our system. The fields used are common to all users in system. """
....
class Customer(models.Model):
"""A Class to represent a Customer in System """
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
现在,我正在尝试弄清楚如何允许用户创建与他的user_type(客户/卖方)相对应的个人资料。而更令人困惑的部分是如何为我的CustomerSerializer
或SellerSerializer
这是我要使用的权限类:
class UpdateCustomerProfile(permissions.BasePermission):
"""Allow users to edit their own profile """
def has_object_permission(self, request, view, obj):
"""Check if user is trying to edit their own profile"""
return obj.user.id == request.user.id
这是客户序列化程序:
class CustomerSerializer(serializers.ModelSerializer):
"""A Serizlier class for customer """
class Meta:
model = models.Customer
fields = ('user', 'first_name', 'last_name', 'dob', 'gender')
def create(self, validated_data):
"""Create and return a new customer."""
CustomerViewSet:
class CustomerViewSet(viewsets.ModelViewSet):
"""Handle creating reading and updating Users in system"""
serializer_class = serializers.CustomerSerializer
queryset = models.User.objects.filter( user_type = "CS" )
authentication_classes = (TokenAuthentication,)
permission_classes = (permissions.UpdateCustomerProfile,)
但是我得到一个错误
/ api / customer-profile /中的AttributeError 尝试获取序列化程序
user
上字段CustomerSerializer
的值时,出现AttributeError。 序列化程序字段的名称可能不正确,并且与User
实例上的任何属性或键都不匹配。 原始异常文本为:“用户”对象没有属性“用户”。
我是Django的新手,所以不确定这是一种方法还是做错了什么。我怎样才能解决这个问题?任何遵循类似策略的示例项目也将非常有帮助。
答案 0 :(得分:2)
由于您的序列化程序用于Customer
,因此您的查询集应用于Customer
:
queryset = models.Customer.objects.filter(user=request.user)
例如,如果您只想访问当前Customer
的{{1}}个人资料。
答案 1 :(得分:0)
user
答案 2 :(得分:0)
嘿,下面有我的代码可用于序列化多个用户类型的注册。我遵循了这个规则:https://www.freecodecamp.org/news/nested-relationships-in-serializers-for-onetoone-fields-in-django-rest-framework-bdb4720d81e6/
这是我的模型。py:
from django.contrib.auth.models import AbstractUser
from django.db import models
class User(AbstractUser):
is_individual = models.BooleanField(default=False)
is_company = models.BooleanField(default=False)
class Company(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
company_name = models.CharField(max_length=100)
email_address = models.EmailField(max_length=254, blank=True, null=True)
class Individual(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
email_address = models.EmailField(max_length=254)
这是我的serializers.py:
from rest_framework import serializers
from classroom.models import User, Individual, Company
from django.contrib.auth import authenticate
class IndividualSerializer(serializers.ModelSerializer):
class Meta:
model = Individual
fields = ('user', 'email_address')
class CompanySerializer(serializers.ModelSerializer):
class Meta:
model = Company
fields = ('user', 'email_address', 'company_name')
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('id', 'username', 'password', 'is_individual', 'is_company')
extra_kwargs = {'password': {'write_only': True}}
class IndividualRegisterSerializer(serializers.ModelSerializer):
user = UserSerializer(required=True)
class Meta:
model = Individual
fields = ('user', 'email_address')
extra_kwargs = {'password': {'write_only': True}, 'username': {'write_only': True}}
def create(self, validated_data, *args, **kwargs):
user = User.objects.create_user(validated_data['user']['username'], validated_data['email_address'], validated_data['user']['password'])
individual = Individual.objects.create(user=user, email_address=validated_data.pop('email_address'))
return individual
class CompanyRegisterSerializer(serializers.ModelSerializer):
user = UserSerializer(required=True)
class Meta:
model = Company
fields = ('user', 'company_name', 'email_address')
extra_kwargs = {'password': {'write_only': True}, 'username': {'write_only': True}}
def create(self, validated_data, *args, **kwargs):
user = User.objects.create_user(validated_data['user']['username'], validated_data['email_address'],
validated_data['user']['password'])
company = Company.objects.create(user=user, email_address=validated_data.pop('email_address'), company_name=validated_data.pop('company_name'))
return company
class IndividualLoginSerializer(serializers.Serializer):
username = serializers.CharField()
password = serializers.CharField()
def validate(self, data):
individual = authenticate(**data)
if individual and individual.is_active:
return individual
raise serializers.ValidationError("Incorrect Credentials")
class Meta:
fields = ['username','password','is_individual','is_company']
extra_kwargs = {'is_individual': {'required': False},
'is_company': {'required': False}}
这是我的api.py:
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework import generics, permissions
from knox.models import AuthToken
from ..serializers import \
UserSerializer, \
IndividualRegisterSerializer, CompanyRegisterSerializer, \
class RegisterIndividualAPI(generics.GenericAPIView):
serializer_class = IndividualRegisterSerializer
def post(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
individual = serializer.save()
individual_data = IndividualSerializer(individual, context=self.get_serializer_context()).data
return Response({
"individual": individual_data,
"username": individual.user.username,
"token": AuthToken.objects.create(individual.user)[1]
})
class RegisterCompanyAPI(generics.GenericAPIView):
serializer_class = CompanyRegisterSerializer
def post(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
company = serializer.save()
company_data = CompanySerializer(company, context=self.get_serializer_context()).data
return Response({
"company": company_data,
"username": company.user.username,
"token": AuthToken.objects.create(company.user)[1]
})
class LoginCompanyAPI(generics.GenericAPIView):
serializer_class = CompanyLoginSerializer
def post(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
company = serializer.validated_data
company_data = CompanySerializer(company, context=self.get_serializer_context()).data
return Response({
"company": company_data,
"username": company.user.username,
"token": AuthToken.objects.create(company.user)[1]
})
这是我的API POST请求的正文:
{
"user": {
"username":"nind5",
"password": "123456",
"is_individual" : "True",
"is_company" : "False"
},
"email_address":"n@gmail.com"
}
我也使用了此资源https://www.youtube.com/watch?v=0d7cIfiydAc&t=437s。这段视频中还介绍了诺克斯。
此外,请使用此在线工具查看您的db(db.sqlite3)表:https://sqliteonline.com/
最好, 尼克