在我的服务中,注册用户时,必须创建两个实体:用户和公司,用户实体将立即链接到公司。
为此,我创建了一个端点,在其中使用两个序列化器(用于用户和公司)。但这个解决方案存在一些问题:
class UserCreateViewSet(mixins.CreateModelMixin,
viewsets.GenericViewSet):
"""
Creates user accounts
"""
queryset = User.objects.all()
serializer_class = CreateUserSerializer
permission_classes = (AllowAny,)
REQUIRED_FIELDS = (
'email', 'password',
'position', 'company_name',
'phone_number'
)
def create(self, request, *args, **kwargs):
data = request.data
provided_fields = set(data.keys())
for field in self.REQUIRED_FIELDS:
if field not in provided_fields:
return Response(
{"detail":f"{field} not provided"},
status=400
)
# --- Creating company for user
data['name'] = data['company_name']
company_serializer = CompanyReducedSerializer(data=request.data)
company_serializer.is_valid(raise_exception=True)
self.perform_create(company_serializer)
data['company'] = company_serializer.data['id']
# ---
# Code from super()
# --- Creating user
user_serializer = self.get_serializer(data=request.data)
user_serializer.is_valid(raise_exception=True)
self.perform_create(user_serializer)
headers = self.get_success_headers(user_serializer.data)
# ---
return Response(
status=201,
data=user_serializer.data,
headers=headers
)
我考虑过使用多表继承的选项,但由于某些原因,这个解决方案不适合我。公司和用户实体必须分开。
我建议对您的代码进行一些更改。
其中一种方法可以如下。
from rest_framework import serializers
class CreateUserSerializer(serializers.Serializer):
email = serializers.EmailField(required=True)
password = serializers.CharField(required=True)
position = serializers.CharField(required=True)
company_name = serializers.CharField(required=True)
phone_number = serializers.CharField(required=True)
from rest_framework import mixins, viewsets
from rest_framework.status import HTTP_201_CREATED
class UserViewSet(mixins.CreateModelMixin, viewsets.GenericViewSet):
...
def create(self, request, *args, **kwargs):
# this serializer will take care of your required fields
data_serializer = CreateUserSerializer(request.data)
data_serializer.is_valid(raise_exception=True)
company_serializer = CompanyCreateSerializer(data=request.data)
company_serializer.is_valid(raise_exception=True)
company = company_serializer.save()
# format data required for user creation
data = {"company": company, "email": email}
user_serializer = UserCreateSerializer(data=data)
user_serializer.is_valid(raise_exception=True)
user_serializer.save()
return Response(
data=user_serializer.data,
status=HTTP_201_CREATED
)
其他方法可以是公司或用户序列化程序的
create
方法,具体取决于您想要如何创建相关对象
例如
class UserCreateSerializer(ModelSerializer):
...
def create(self, validated_data: dict):
company_sz = CompanySerializer(data=<YOUR_DATA>)
compant_sz.is_valid(raise_exception=True)
company_sz.save()
user = super().create(validated_data)
return user