我是 djoser 的新手,我是验证用户的用户。然后,我希望在user/me
访问时显示患者信息,但我将其覆盖以也显示患者详细信息,但出现此错误
错误
AttributeError: Got AttributeError when attempting to get a value for field `blood_sugar_level` on serializer `PatientInfoSerializer`.
序列化器字段可能命名不正确,并且与UserProfile
实例上的任何属性或键都不匹配。原始异常文本为:“UserProfile”对象没有属性“blood_sugar_level”。
模型.py
from django.db import models
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin, BaseUserManager
from django.db import models
from django.conf import settings # used to retreive AUTH_USER_MODEL from settings.py file
# These two imports allow for the default user model to be customized or overrided
from django.contrib.auth.models import AbstractBaseUser
from django.contrib.auth.models import PermissionsMixin
# Default model manager
from django.contrib.auth.models import BaseUserManager
class UserProfileManager(BaseUserManager):
"""Manager for user profiles"""
def create_user(self, email, name, password=None):
"""Create a new user profile"""
if not email:
raise ValueError('Users must have an email address')
email = self.normalize_email(email)
user = self.model(email=email, name=name,)
user.set_password(password) #This hashes the user password so we do not have plain text passwordfs in our db
user.save(using=self._db)
return user
def create_superuser(self, email, name, password):
"""Create and save a new superuser with given details"""
user = self.create_user(email, name, password)
user.is_superuser = True
user.is_staff = True
user.save(using=self._db)
return user
class UserProfile(AbstractBaseUser, PermissionsMixin):
"""Database model for patients in the system"""
email = models.EmailField(max_length=255, unique=True)
name = models.CharField(max_length=255)
#phone?
#address?
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
objects = UserProfileManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['name']
def get_full_name(self):
"""Retrieve full name for user"""
return self.name
def get_short_name(self):
"""Retrieve short name of user"""
return self.name
def __str__(self):
"""Return string representation of user"""
return self.email
class PatientInfo(models.Model):
"""Database model for patient information"""
user_profile = models.ForeignKey(
settings.AUTH_USER_MODEL, # This points to the user model used for authentication in settings.py, if we need to change the model used change it there
on_delete=models.CASCADE
)
# Patient insulin injected choices
YES = 'YES'
NO = 'NO'
IS_INSULIN_INJECTED_CHOICES = [
(YES, 'YES'),
(NO, 'NO'),
]
inject_date = models.DateField(auto_now_add=True, auto_now=False, blank= False)
inject_time = models.TimeField(auto_now_add=True, auto_now=False, blank= False)
blood_sugar_level = models.CharField(max_length=20, blank= False)
is_insulin_injected = models.CharField(choices = IS_INSULIN_INJECTED_CHOICES, default = 1, max_length=3, blank= False)
quantity = models.CharField(max_length=10, blank= False)
inject_area = models.TextField(blank= False)
序列化程序.py
from accounts import models
from djoser.serializers import UserCreateSerializer
from rest_framework import serializers
from django.contrib.auth import get_user_model
User = get_user_model()
class UserCreateSerializer(UserCreateSerializer):
class Meta(UserCreateSerializer.Meta):
model = User
fields = ('id','email','name','password')
class UserProfileSerializer(serializers.ModelSerializer):
"""Serializes a user profile object"""
class Meta:
model = models.UserProfile
fields = ('id', 'email', 'name', 'password')
extra_kwargs = {
'password': {
'write_only': True,
'style': {'input_type': 'password'}
}
}
def create(self, validated_data):
"""Create and return a new user"""
user = models.UserProfile.objects.create_user(
email=validated_data['email'],
name=validated_data['name'],
password=validated_data['password']
)
return user
def update(self, instance, validated_data):
"""Handle updating user account"""
if 'password' in validated_data:
password = validated_data.pop('password')
instance.set_password(password)
return super().update(instance, validated_data)
class PatientInfoSerializer(serializers.ModelSerializer):
"""Serializes patient Info objects"""
class Meta:
model = models.PatientInfo # Points this serializer to the patient info model
fields = ('id','user_profile','inject_date', 'inject_time', 'blood_sugar_level', 'is_insulin_injected', 'quantity', 'inject_area',)
extra_kwargs = {
'user_profile': {
'read_only': True,
}
}
视图.py
from django.shortcuts import render
from rest_framework import viewsets
from rest_framework.authentication import TokenAuthentication
from rest_framework.permissions import IsAuthenticated
from rest_framework.authtoken.views import ObtainAuthToken
from rest_framework.settings import api_settings
from accounts import serializers # Will use this to tell API what data to exect when making a POST PUT PATCH request to API
from accounts import models
from accounts import permissions
class PatientInfoViewSet(viewsets.ModelViewSet):
"""Handles creating, reading and updating patient info objects"""
authentication_classes = (TokenAuthentication,)
serializer_class = serializers.PatientInfoSerializer # This points to the
queryset = models.PatientInfo.objects.all()
permission_classes = (permissions.UpdateOwnReading, IsAuthenticated,) # Validates that a user is authenticated to read or modify objects
def perform_create(self, serializer): # overridijg this function so that when a user tries to create an object they are validated as the current user
"""Sets the patient profile to the logged in user"""
serializer.save(user_profile=self.request.user) # This sets the user profile to the current user from the serializer passed in