我正在尝试构建我的第一个Django后端项目,所以我正在尝试创建一个REST API端点,它可以从前端获取用户注册数据并保存在数据库中,如果有效的话。我正在尝试将额外的用户信息保存在一个名为Player的新模型中,并使用一对一字段将其链接到默认的用户模型。
当我从前端接收到包含数据的json文件时,用户模型中创建了一个包含数据的新用户,同时在播放器模型中创建了一个新行,它连接到我们刚刚在用户模型中创建的用户。但问题是字段“height”和“handicap”仍然为空。
我不知道如何将“身高”和“障碍”参数保存到新的Player示例中。
这是我的models.py文件:
from django.db import models
from django.core.validators import MaxValueValidator, MinValueValidator
from django.contrib.auth.models import User
from django.dispatch import receiver
from django.db.models.signals import post_save
from datetime import *
# This model extend the basic built-in User model, by adding additional information on the uesr like
# handicap score anf height.
class Player(models.Model):
def __str__(self):
return self.user.username
user = models.OneToOneField(User, on_delete=models.CASCADE) # connecting this model to the User model
# (cascade means when deleting a user row in the user table
# the match row in this table will automatically will be deleted)
handicap = models.IntegerField(default=0, validators=[MinValueValidator(0), MaxValueValidator(28)])
height = models.IntegerField(default=0, validators=[MinValueValidator(0), MaxValueValidator(250)])
registration_date = models.DateTimeField(default=datetime.now())
#a listener that listen to the User model, if a new user as been save, it creates a new row in the player model with the new user in the user field
@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
if created: # if a new user created in the User model
Player.objects.create(user=instance) # creating a new row in player, inserting the new user instance to the user field
# if a User is saved we update the user instance to the player user field
@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
instance.profile.save()
这是我的serializers.py文件:
from rest_framework import serializers
from django.contrib.auth.models import User
from rest_framework.validators import UniqueValidator
from django.contrib.auth.password_validation import validate_password
from django.core.validators import MaxValueValidator, MinValueValidator
from .models import Player
# class serializer that handel the data from user registration
class RegisterSerializer(serializers.ModelSerializer):
first_name = serializers.CharField(required=True)
last_name = serializers.CharField(required=True)
email = serializers.EmailField(required=True, validators=[UniqueValidator(queryset=User.objects.all())]) # making sure that the email that the user entered have not being used by another user
password = serializers.CharField(write_only=True, required=True, validators=[validate_password]) # checking that the password is valid
password2 = serializers.CharField(write_only=True, required=True)
height = serializers.IntegerField(validators=[MinValueValidator(0), MaxValueValidator(250)])
handicap = serializers.IntegerField(validators=[MinValueValidator(0), MaxValueValidator(28)])
class Meta: # nested class that gives the serializer details
model = User
fields = ('first_name', 'last_name', 'email', 'password', 'password2', 'height', 'handicap')
# overriding the built-in validation method of the model serializer
def validate(self, attrs):
if attrs['password'] != attrs['password2']: # if the 2 passwords on the form don't match
raise serializers.ValidationError({'password': "passwords don't match!"}) # raising an error
return attrs
# overriding the built-in create method
def create(self, validated_data):
# creating a user instance with the data came from the registration
user = User.objects.create(username=validated_data['email'], first_name=validated_data['first_name'], last_name=validated_data['last_name'], email=validated_data['email'], password=validated_data['password'])
user.save() # saving the user registration data to the database
player = Player.objects.get(user=user)
player.height = validated_data['height']
player.handicap = validated_data['handicap']
player.save()
return user
这是我的views.py文件:
from rest_framework import generics
from .serializers import *
# Create your views here.
class RegistrationView(generics.CreateAPIView):
queryset = User.objects.all()
serializer_class = RegisterSerializer
这是我的urls.py文件:
from django.urls import path
from .views import RegistrationView
urlpatterns = [
path('registration/', RegistrationView.as_view(), name='registration')
]
是否有人知道如何将“身高”和“差点”也保存到播放器模型中?
2条答案
按热度按时间py49o6xq1#
您所面临的问题可以通过序列化程序关系来解决,更具体地说,可以通过嵌套关系来解决。
我已经尽我所能地保存了你的代码。尽管如此,一些修改是必要的,或者只是为了让代码更干净而做的。
models.py
删除了“registration_date”字段。抽象用户模型已经有一个名为“date_joined”的字段,无需存储相同的信息。另外,第二个函数“保存_user_profile”也不是必需的。
serializers.py
已创建嵌套在RegistrationSerializer中的PlayerSerializer。通过排除“user”字段来表示“handicap”和“height”字段。
在create方法中,从字典中取出键,使用**kwargs来获得更简洁的格式,然后使用键来更新关系值。
views.py urls.py保持不变。
hsgswve42#
你在序列化器中创建了用户对象。在下一行中,你尝试从播放器模型中获取用户示例。实际上,那个用户的示例还没有在播放器模型中创建。所以首先你必须在播放器模型中创建那个用户示例。