【问题标题】:how to fix django Model instance如何修复 django 模型实例
【发布时间】:2020-12-25 11:25:18
【问题描述】:

错误消息 ValueError:无法分配“”:“Diagnoses.owner”必须是“Patient”实例

当我尝试创建新卡或诊断时出现上述错误。 卡片和诊断是患者的一个实例,就像患者拥有卡片和诊断一样。患者类有一个引用用户的外键。 这是代码

views.py

    from django.shortcuts import render
from rest_framework.generics import ListCreateAPIView, RetrieveUpdateDestroyAPIView
from .serializers import PatientsSerializer, PatientsCardSerializer, PatientsDiagnosesSerializer
from .models import Patient, Card, Diagnoses
from rest_framework import permissions
from .permissions import IsOwner


# Patient Views
class PatientListAPIView(ListCreateAPIView):
    serializer_class = PatientsSerializer
    queryset = Patient.objects.all()
    permission_classes = (permissions.IsAuthenticated, IsOwner,) 
    def perform_create(self, serializer):
        return serializer.save(owner=self.request.user)
    def get_queryset(self):
        return self.queryset.filter(owner=self.request.user)

class PatientDetailAPIView(RetrieveUpdateDestroyAPIView):
    serializer_class = PatientsSerializer
    permission_classes = (permissions.IsAuthenticated, IsOwner,)
    queryset = Patient.objects.all()
    lookup_field = "id"
    def get_queryset(self):
        return self.queryset.filter(owner=self.request.user)


class PatientCardListAPIView(ListCreateAPIView):
    serializer_class = PatientsCardSerializer
    queryset = Card.objects.all()
    permission_classes = (permissions.IsAuthenticated,) 
    def perform_create(self, serializer):
        return serializer.save(owner=self.request.user)
    def get_queryset(self):
        return self.queryset.filter(owner=self.request.user)

class PatientCardDetailAPIView(RetrieveUpdateDestroyAPIView):
    serializer_class = PatientsCardSerializer
    permission_classes = (permissions.IsAuthenticated, IsOwner,)
    queryset = Card.objects.all()
    lookup_field = "id"
    def get_queryset(self):
        return self.queryset.filter(owner=self.request.user)



class PatientDiagnosesListAPIView(ListCreateAPIView):
    serializer_class = PatientsDiagnosesSerializer
    queryset = Diagnoses.objects.all()
    permission_classes = (permissions.IsAuthenticated,) 
    def perform_create(self, serializer):
        return serializer.save(owner=self.request.user)
    def get_queryset(self):
        return self.queryset.filter(owner=self.request.user)

class PatientDiagnosesDetailAPIView(RetrieveUpdateDestroyAPIView):
    serializer_class = PatientsDiagnosesSerializer
    permission_classes = (permissions.IsAuthenticated, IsOwner,)
    queryset = Diagnoses.objects.all()
    lookup_field = "id"
    def get_queryset(self):
        return self.queryset.filter(owner=self.request.user)

Models.py

class Patient(models.Model):
    name = models.CharField(max_length=255, null=True)
    country = models.CharField(max_length=255, null=True)
    state = models.CharField(max_length=255, null=True)
    phone = models.CharField(max_length=255, null=True)
    email = models.CharField(max_length=255, null=True)
    owner = models.ForeignKey(to=User, null=True, on_delete=models.CASCADE)
    def __str__(self):
        return self.name
class Card(models.Model):    
    name = models.CharField(max_length=255, null=True)
    card_number = models.CharField(max_length=255, null=True)    
    owner = models.OneToOneField(Patient, null=True, blank=True, on_delete=models.CASCADE)
    def __str__(self):
        return (self.patient.name)+"'s card"
   
class Diagnoses(models.Model):
    sickness = models.CharField(max_length=255, null=True)
    note = models.TextField(max_length=255, null=True)   
    owner = models.ForeignKey(Patient, null=True, on_delete=models.SET_NULL)
    def __str__(self):
        return (self.patient.name)+"'s diagnoses"

【问题讨论】:

  • 向我们展示您用于创建实例的代码。模型没有问题。这应该是问题所在。
  • 已添加假定创建实例的代码。我编辑了帖子并添加了views.py
  • 我有几个问题,1.) 回溯是否指向views.py??? 2.) 另外,User 不是Patience,所以你不能只依赖User 实例,除非UserPatience 有交叉引用。如果存在交叉引用,我们可以通过将其重定向到该对象来解决它。如果您只有单向引用,我建议将该对象 User 查询到 Patience。我可以回答,但让我们看看你会采取什么行动。
  • 这里是患者模型
  • 我已经看到了,我的意思是这个return serializer.save(owner=self.request.user)self.request.user 不是 Patient 对象。这是一个用户对象。因此它会发出错误。我的建议是将这个User 对象查询到Patient 对象。为了以防万一,我可能会在这个答案中加上额外的上下文。

标签: django django-models django-rest-framework django-views


【解决方案1】:

到目前为止,self.request.user 是一个 User 对象。因此,您无法将其保存到 API 或模型中。为了清楚起见,它不是 Patient 对象。

根据您的情况,我会将Patient 对象与User 对象(如果这是单向引用对象)排队,并将其放入参数中并执行 save() 方法。

class PatientCardListAPIView(ListCreateAPIView):
    serializer_class = PatientsCardSerializer
    queryset = Card.objects.all()
    permission_classes = (permissions.IsAuthenticated,) 

    def perform_create(self, serializer):
        getPatientFromUser = Patient.objects.get(owner=self.request.user)
        # getPatientFromUser returns `Patient` Instance. So you could bind it in `Card` Model.
        return serializer.save(owner=getPatientFromUser)

    def get_queryset(self):
        return self.queryset.filter(owner=self.request.user)

注意事项:

  1. 这是一种单向参考解决方案。 (User 被称为Patient
  2. 如果您在 UserPatience 之间存在交叉引用关系(其中 User 和 Patience 之间有一个 ForeignKey),则声明您的 User 模型。
  3. 解决方案向用户查询患者。由于用户与该外部对象不兼容。

【讨论】:

  • 对不起,我如何声明选项 2 的用户模型
  • 哦,我以为你明确声明了User,我想你现在可以选择单向引用。
  • 您可以使用子类AbstractBaseUserAbstractUser 声明您的User 类。但这需要重新声明用户字段。这意味着它将更加可定制,但您必须自己声明您的字段。查看有关这些类的文档以获取更多信息
  • 如果您暂时不打算更改您的User 模型,那么我建议您使用我在上面提供的单向参考解决方案。 (如果这看起来足够,请将其标记为已接受的答案)
  • 当我选择您在此处给出的第一个选项时,错误 MultipleObjectsReturned at /patient/card get() returned more than one Patient -- 它返回了 3!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-08
  • 2016-02-15
  • 1970-01-01
  • 2012-08-22
  • 2018-03-21
相关资源
最近更新 更多