我正在做的是django 2项目调用api到django 1项目预约Appointment
表中的约会并将详细信息保存到BookAppt
表中。
我正在尝试使用视图将数据从api调用保存到api。其他一切都有效但是,用户模型userId
的外键给我这个错误:ValueError: Cannot assign "4": "BookAppt.patientId" must be a "MyUser" instance.
我不知道是什么问题,因为我说过与BookAppt表API具有相同值的相同帖子并且它正常工作。但是当使用API调用保存时,它给了我这个错误。
更新错误
根据给出的答案更新我的代码后,我现在收到此错误。 {"patientId":["This field is required."]}
即使我已经指定它,仍然不知道为什么。
请帮助,因为我已经被困在这个部分2天了。
这是我的代码:
更新了代码,请注意django 2呼叫django 1
model.py
django 1
class Appointments (models.Model):
patientId = models.IntegerField()
clinicId = models.CharField(max_length=10)
date = models.DateField()
time = models.TimeField()
created = models.DateTimeField(auto_now_add=True)
ticketNo = models.IntegerField()
STATUS_CHOICES = (
("Booked", "Booked"),
("Done", "Done"),
("Cancelled", "Cancelled"),
)
status = models.CharField(max_length=20, choices=STATUS_CHOICES, default="Booked")
django 2
class MyUser(AbstractUser):
userId = models.AutoField(primary_key=True)
gender = models.CharField(max_length=6, blank=True, null=True)
nric = models.CharField(max_length=9, blank=True, null=True)
birthday = models.DateField(blank=True, null=True)
birthTime = models.TimeField(blank=True, null=True)
class BookAppt(models.Model):
clinicId = models.CharField(max_length=20)
patientId = models.ForeignKey(MyUser, on_delete=models.CASCADE)
scheduleTime = models.DateTimeField()
ticketNo = models.CharField(max_length=5)
status = models.CharField(max_length=20)
串行
django 1
class AppointmentsSerializer(serializers.ModelSerializer):
class Meta:
model = Appointments
fields = ('id', 'patientId', 'clinicId', 'date', 'time', 'created', 'ticketNo', 'status')
django 2
class MyUserSerializer(serializers.ModelSerializer):
class Meta:
model = MyUser
fields = ('userId', 'username', 'email', 'first_name', 'last_name', 'gender', 'nric', 'birthday', 'birthTime')
read_only_fields = ('userId',)
class BookApptSerializer(serializers.ModelSerializer):
patientId = MyUserSerializer(many=False)
class Meta:
model = BookAppt
fields = ('id', 'patientId', 'clinicId', 'scheduleTime', 'ticketNo', 'status')
view.py
django 1
class AppointmentsViewSet(viewsets.ModelViewSet):
permission_classes = [AllowAny]
queryset = Appointments.objects.all()
serializer_class = AppointmentsSerializer
django 2
@csrf_exempt
def my_django_view(request):
if request.method == 'POST':
r = requests.post('http://127.0.0.1:8000/api/makeapp/', data=request.POST)
else:
r = requests.get('http://127.0.0.1:8000/api/makeapp/', data=request.GET)
if r.status_code == 201 and request.method == 'POST':
data = r.json()
patient = request.data['patientId']
patientId = MyUser.objects.get(id=patient)
saveget_attrs = {
"patientId": patientId,
"clinicId": data["clinicId"],
"scheduleTime": data["created"],
"ticketNo": data["ticketNo"],
"status": data["status"],
}
saving = BookAppt.objects.create(**saveget_attrs)
return HttpResponse(r.text)
elif r.status_code == 200: # GET response
return HttpResponse(r.json())
else:
return HttpResponse(r.text)
class BookApptViewSet(viewsets.ModelViewSet):
permission_classes = [AllowAny]
queryset = BookAppt.objects.all()
serializer_class = BookApptSerializer
答案 0 :(得分:1)
您的约会模型 - 您使用MyUser模型而不是其ID,
因此,将外键引用模型的名称设为patient
而不是patient_id
是有意义的,所以
class Appointments (models.Model):
patient = models.ForeignKey(MyUser, on_delete=models.CASCADE)
clinicId = models.CharField(max_length=10)
date = models.DateField()
time = models.TimeField()
created = models.DateTimeField(auto_now_add=True)
ticketNo = models.IntegerField()
STATUS_CHOICES = (
("Booked", "Booked"),
("Done", "Done"),
("Cancelled", "Cancelled"),
)
status = models.CharField(max_length=20, choices=STATUS_CHOICES, default="Booked")
比你的serializers.py:
class MyUserSerializer(serializer.ModelSerializer):
# Whatever you like to serialize
class Meta:
model = MyUser
然后,还需要调整Appintment序列化器:
class AppointmentsSerializer(serializers.ModelSerializer):
# Notice this - the patient is serailized using MyUserSerializer
patient = MyUserSerializer(many=False, read_only=False)
valid_time_formats = ['%H:%M', '%I:%M%p', '%I:%M %p']
time = serializers.TimeField(format='%I:%M %p', input_formats=valid_time_formats)
created = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", read_only=True)
class Meta:
model = Appointments
# Now, you work with patient object, not with patientId
# clinicId can still be an Id as long as it's not a foreign key
fields = ('id', 'patient', 'clinicId', 'date', 'time', 'created', 'ticketNo', 'status')
class BookApptSerializer(serializers.ModelSerializer):
# Same here - the patient is serailized using MyUserSerializer
patient = MyUserSerializer(many=False, read_only=False)
valid_time_formats = ['%Y-%m-%d %H:%M', '%Y-%m-%d %I:%M%p', '%Y-%m-%d %I:%M %p']
scheduleTime = serializers.DateTimeField(format="%Y-%m-%d %I:%M %p", input_formats=valid_time_formats)
class Meta:
model = BookAppt
fields = ('id', 'patient', 'clinicId', 'scheduleTime', 'ticketNo', 'status')
现在,在您看来,您必须明确阅读患者:
patient = MyUser.objects.get(id=patientId)
如果pateintId是你确定它存在的id的整数值, 然后
saveget_attrs = {
# This has to be object, not the id, that's why it was breaking
"patient": patient,
"clinicId": data["clinicId"],
"scheduleTime": data["created"],
"ticketNo": data["ticketNo"],
"status": data["status"],
}
savingIntoBookApptTable = BookAppt.objects.create(**saveget_attrs)
return HttpResponse(r.text)
关于您可以在Appointments
模型中使用的日期时间字段:
time_scheduled = models.DateTimeField(default=datetime.now, blank=True)
就像你的created = models.DateTimeField(auto_now_add=True)
一样。
您可以使用
default
default=lambda self.date, self.time: scheduled(self.date, self.time)
所以它会像:
time_scheduled = models.DateTimeField(default=lambda self.date, self.time: scheduled(self.date, self.time), blank=True)
其中scheduled
计算并格式化您提供的日期时间和时间 - 您的帮助程序功能。
这将在创建对象时自动分配时间,但您可以
如果您愿意,请稍后再说明。使用这样的字段,您可以排除其中一个表示日期和时间的字段。
示例视图格式 - 仅用于演示如何阅读用户:
from rest_framework.renderers import JSONRenderer
from rest_framework.permissions import AllowAny
from rest_framework.decorators import api_view, renderer_classes, permission_classes
# If you need GET as well, this would be @api_view(['POST', 'GET'])
@api_view(['POST'])
@renderer_classes((JSONRenderer,))
@permission_classes([AllowAny,])
def read_user_view(request):
try:
user_id = request.data['user_id']
user = User.objects.get(id=int(user_id))
except ObjectDoesNotExist as e:
user = User.objects.create(id=user_id)
# Any other processing if user created
serializer = MyUserSerializer(user, many=False)
return Response(serializer.data)