DRF-如何使用APIView保存外键数据
DRF-How to save foreign keys data using APIView
各位,我绝对是DjangoRestFramework的初学者。我对处理 DRF 中的关系感到困惑。如何使用 APIView 保存外键数据?
型号
class User(AbstractUser):
email = models.EmailField(max_length=255, unique=True)
is_client = models.BooleanField(default=False)
is_professional = models.BooleanField(default=False)
class Client(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='client')
##
class Professionals(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='professional')
##
class HireProfessional(models.Model):
client = models.ForeignKey(Client, related_name='user', on_delete=models.CASCADE)
professional = models.ForeignKey(Professionals, on_delete=models.CASCADE, related_name="professsional")
hire_start_date_time = models.DateTimeField(default=timezone.now)
序列化器
class ProfessionalSerializer(serializers.ModelSerializer):
profilePicture = serializers.ImageField(allow_empty_file=True, use_url='professional/profiles', required=False)
skill = SkillSerializer(many=True,read_only=True)
class Meta:
model = Professionals
fields = fields = ['first_name', 'last_name', 'profilePicture', 'profession', 'phone_number', 'experience', 'skill', 'charge_fee', 'about_me']
class ClientSerializer(serializers.ModelSerializer):
class Meta:
model = Client
fields = ['user_id', 'first_name', 'last_name', 'phone_number', 'profilePicture']
class UserSerializer(serializers.ModelSerializer):
client = ClientSerializer()
professional = ProfessionalSerializer()
class Meta:
model = User
fields = ('email', 'username', 'is_client', 'is_professional', 'client', 'professional')
class HireProfessionalSerializer(serializers.ModelSerializer):
client = ClientSerializer()
professional = professionalSerializer()
class Meta:
model = HireProfessional
fields = ['id','client', 'professional', 'hire_start_date_time']
观看次数##已编辑
class HireProfessionalCreateApp(APIView):
permission_classes = (IsAuthenticated, IsClientUser,)
def current_user(self):
user = self.request.user.client
return user
def post(self, request, username, format=None):
try:
professional = Professionals.objects.get(user__username=username)
# print('hello', professional.user_id)
data = request.data
data['client'] = self.current_user()
data['professional'] = professional.user_id
serializer = HireProfessionalSerializer(data=data)
data = {}
if serializer.is_valid():
hire = serializer.save()
hire.save()
return JsonResponse ({
"message":"professional hired success.",
# "remaning_time":remaning_datetime,
"success" : True,
"result" : serializer.data,
"status" : status.HTTP_201_CREATED
})
else:
data = serializer.errors
print(data)
return Response(serializer.data)
except Professionals.DoesNotExist:
return JsonResponse ({"status":status.HTTP_404_NOT_FOUND, 'message':'professional does not exists'})
这是一款招聘应用。
客户能够聘请专业人士
客户端=登录用户
professional=通过 URL
传递了 id 或用户名
赞:path('hire-professional/<professional id or username>', views)
有人知道吗?如何解决。
考虑使用 ModelViewSet
而不是 APIView
,因为您要直接修改 HireProfessional
模型。此外,该模型对 Client
和 Professional
使用 ForeignKey
字段,您 而不是 需要在 HireProfessionalSerializer
中包含它们各自的序列化程序。
仅实施 ModelViewSet
(并使用 router 将其添加到 urls.py
)将意味着用户可以 select 客户和专业人士自己,这意味着我们还没有完成。建议在 DRF 中使用 router
而不是手动将所有视图添加到 urls.py
。
您可以使用 ModelViewSet 覆盖自动填充序列化程序字段的 perform_create
and perform_update
函数。 :
默认创建函数
def perform_create(self, serializer):
serializer.save()
自动填充示例
def perform_create(self, serializer):
# client is derived from logged in user
client = Client.objects.get(user=self.request.user)
# Autofill FK Client.
serializer.save(client=client)
现在客户端已自动填充,但专业版还没有。如果你还想自动填充专业人士,你将不得不考虑使用 nested router,因为你想从 URL 中检索 PK(id)。如果你这样做,你的 URL 将看起来像这样:
url='/professionals/{professionals_pk}/hire/'
我希望这能让您知道从哪里开始。如果您有任何问题,请告诉我。
各位,我绝对是DjangoRestFramework的初学者。我对处理 DRF 中的关系感到困惑。如何使用 APIView 保存外键数据?
型号
class User(AbstractUser):
email = models.EmailField(max_length=255, unique=True)
is_client = models.BooleanField(default=False)
is_professional = models.BooleanField(default=False)
class Client(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='client')
##
class Professionals(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='professional')
##
class HireProfessional(models.Model):
client = models.ForeignKey(Client, related_name='user', on_delete=models.CASCADE)
professional = models.ForeignKey(Professionals, on_delete=models.CASCADE, related_name="professsional")
hire_start_date_time = models.DateTimeField(default=timezone.now)
序列化器
class ProfessionalSerializer(serializers.ModelSerializer):
profilePicture = serializers.ImageField(allow_empty_file=True, use_url='professional/profiles', required=False)
skill = SkillSerializer(many=True,read_only=True)
class Meta:
model = Professionals
fields = fields = ['first_name', 'last_name', 'profilePicture', 'profession', 'phone_number', 'experience', 'skill', 'charge_fee', 'about_me']
class ClientSerializer(serializers.ModelSerializer):
class Meta:
model = Client
fields = ['user_id', 'first_name', 'last_name', 'phone_number', 'profilePicture']
class UserSerializer(serializers.ModelSerializer):
client = ClientSerializer()
professional = ProfessionalSerializer()
class Meta:
model = User
fields = ('email', 'username', 'is_client', 'is_professional', 'client', 'professional')
class HireProfessionalSerializer(serializers.ModelSerializer):
client = ClientSerializer()
professional = professionalSerializer()
class Meta:
model = HireProfessional
fields = ['id','client', 'professional', 'hire_start_date_time']
观看次数##已编辑
class HireProfessionalCreateApp(APIView):
permission_classes = (IsAuthenticated, IsClientUser,)
def current_user(self):
user = self.request.user.client
return user
def post(self, request, username, format=None):
try:
professional = Professionals.objects.get(user__username=username)
# print('hello', professional.user_id)
data = request.data
data['client'] = self.current_user()
data['professional'] = professional.user_id
serializer = HireProfessionalSerializer(data=data)
data = {}
if serializer.is_valid():
hire = serializer.save()
hire.save()
return JsonResponse ({
"message":"professional hired success.",
# "remaning_time":remaning_datetime,
"success" : True,
"result" : serializer.data,
"status" : status.HTTP_201_CREATED
})
else:
data = serializer.errors
print(data)
return Response(serializer.data)
except Professionals.DoesNotExist:
return JsonResponse ({"status":status.HTTP_404_NOT_FOUND, 'message':'professional does not exists'})
这是一款招聘应用。
客户能够聘请专业人士
客户端=登录用户
professional=通过 URL
传递了 id 或用户名赞:path('hire-professional/<professional id or username>', views)
有人知道吗?如何解决。
考虑使用 ModelViewSet
而不是 APIView
,因为您要直接修改 HireProfessional
模型。此外,该模型对 Client
和 Professional
使用 ForeignKey
字段,您 而不是 需要在 HireProfessionalSerializer
中包含它们各自的序列化程序。
仅实施 ModelViewSet
(并使用 router 将其添加到 urls.py
)将意味着用户可以 select 客户和专业人士自己,这意味着我们还没有完成。建议在 DRF 中使用 router
而不是手动将所有视图添加到 urls.py
。
您可以使用 ModelViewSet 覆盖自动填充序列化程序字段的 perform_create
and perform_update
函数。 :
默认创建函数
def perform_create(self, serializer):
serializer.save()
自动填充示例
def perform_create(self, serializer):
# client is derived from logged in user
client = Client.objects.get(user=self.request.user)
# Autofill FK Client.
serializer.save(client=client)
现在客户端已自动填充,但专业版还没有。如果你还想自动填充专业人士,你将不得不考虑使用 nested router,因为你想从 URL 中检索 PK(id)。如果你这样做,你的 URL 将看起来像这样:
url='/professionals/{professionals_pk}/hire/'
我希望这能让您知道从哪里开始。如果您有任何问题,请告诉我。