foreign key and UI interface

Hi all,
I have a model with

from django.contrib.auth.models import User
class Doctor(models.Model):
    user=models.OneToOneField(User,on_delete=models.CASCADE)

class Patient(models.Model):
    user=models.OneToOneField(User,on_delete=models.CASCADE)
    assignedDoctorId = models.ForeignKey(Doctor, on_delete=models.CASCADE)

in the UI I set a dropdown menu where user select for the patient its doctor

assignedDoctorId=forms.ModelChoiceField(queryset=models.Doctor.objects.all().filter(status=True),empty_label="Name and Department", to_field_name="user_id")

but when I set the doctor in drop down menu following error appears

ValueError: Cannot assign "'2'": "Patient.assignedDoctorId" must be a "Doctor" instance.

I thought to use foreign key to associate each patient to its doctor. Where I wrong?

Please post the view and the form that you’re using.

form.py section

class PatientForm(forms.ModelForm):
   assignedDoctorId=forms.ModelChoiceField(queryset=models.Doctor.objects.all().filter(status=True),empty_label="Name and Department", to_field_name="user_id")

view.py section

def patient_signup_view(request):
    userForm=forms.PatientUserForm()
    patientForm=forms.PatientForm()
    mydict={'userForm':userForm,'patientForm':patientForm}
    if request.method=='POST':
        userForm=forms.PatientUserForm(request.POST)
        patientForm=forms.PatientForm(request.POST,request.FILES)
        if userForm.is_valid() and patientForm.is_valid():
            user=userForm.save()
            user.set_password(user.password)
            user.save()
            patient=patientForm.save(commit=False)
            patient.user=user
            patient.assignedDoctorId=request.POST.get('assignedDoctorId')
            patient=patient.save()
            my_patient_group = Group.objects.get_or_create(name='PATIENT')
            my_patient_group[0].user_set.add(user)
        return HttpResponseRedirect('patientlogin')
    return render(request,'hospital/patientsignup.html',context=mydict)

many thanks

Why do you have this assignment statement?

PatientForm is a model form with the assignedDoctorId field, where it’s being saved and assigned to the local variable patient.

Note: You’re not properly handling the case where one of the forms is invalid. If either form is invalid, you’re going to redirect to patientlogin without saving any data and any indication that something wasn’t saved correctly.

many thanks for your answer and your help

just one more question please:
if I have a table with many doctors registered and each doctor has its id number define using

from django.contrib.auth.models import User

class Doctor(models.Model):
    user=models.OneToOneField(User,on_delete=models.CASCADE)

I would like add many patient to each doctor and each patient have to have a foreignKey to be associate to its Doctor.

in view.py I tried also

patient.assignedDoctorId=Doctor.objects.get(id=request.POST.get('assignedDoctorId'))

maybe I wrong to understand how foreign key works
can you help me? many thanks in advance
maybe have you a tutorial projects? many thanks again for your help

I’m not sure I’m following all the different pieces involved here. Assuming the view you posted earlier is still the current version of that view, please post the forms and the models involved.

Also, if you are getting an error message with a traceback, please post the complete error message and the traceback from the server console.

thank you
form.py

from django import forms
from django.contrib.auth.models import User
from . import models

class AdminSigupForm(forms.ModelForm):
    class Meta:
        model=User
        fields=['first_name','last_name','username','password']
        widgets = {
        'password': forms.PasswordInput()
        }

class DoctorUserForm(forms.ModelForm):
    class Meta:
        model=User
        fields=['first_name','last_name','username','password']
        widgets = {
        'password': forms.PasswordInput()
        }
class DoctorForm(forms.ModelForm):
    class Meta:
        model=models.Doctor
        fields=['address','mobile','department','status']

class PatientUserForm(forms.ModelForm):
    class Meta:
        model=User
        fields=['first_name','last_name','username','password']
        widgets = {
        'password': forms.PasswordInput()
        }
class PatientForm(forms.ModelForm):
       assignedDoctorId=forms.ModelChoiceField(queryset=models.Doctor.objects.all().filter(status=True),empty_label="Name and Department", to_field_name="user_id")
    class Meta:
        model=models.Patient
        fields=['address','mobile']

view.py

from django.shortcuts import render,redirect,reverse
from . import forms,models
from django.db.models import Sum
from django.contrib.auth.models import Group
from django.http import HttpResponseRedirect
from django.core.mail import send_mail
from django.contrib.auth.decorators import login_required,user_passes_test
from datetime import datetime,timedelta,date
from django.conf import settings
from django.db.models import Q
def doctor_signup_view(request):
    userForm=forms.DoctorUserForm()
    doctorForm=forms.DoctorForm()
    mydict={'userForm':userForm,'doctorForm':doctorForm}
    if request.method=='POST':
        userForm=forms.DoctorUserForm(request.POST)
        doctorForm=forms.DoctorForm(request.POST,request.FILES)
        if userForm.is_valid() and doctorForm.is_valid():
            user=userForm.save()
            user.set_password(user.password)
            user.save()
            doctor=doctorForm.save(commit=False)
            doctor.user=user
            doctor=doctor.save()
            my_doctor_group = Group.objects.get_or_create(name='DOCTOR')
            my_doctor_group[0].user_set.add(user)
        return HttpResponseRedirect('doctorlogin')
    return render(request,'hospital/doctorsignup.html',context=mydict)


def patient_signup_view(request):
    userForm=forms.PatientUserForm()
    patientForm=forms.PatientForm()
    mydict={'userForm':userForm,'patientForm':patientForm}
    if request.method=='POST':
        userForm=forms.PatientUserForm(request.POST)
        patientForm=forms.PatientForm(request.POST,request.FILES)
        if userForm.is_valid() and patientForm.is_valid():
            user=userForm.save()
            user.set_password(user.password)
            user.save()
            patient=patientForm.save(commit=False)
            patient.user=user
            patient.assignedDoctorId=Doctor.objects.get(id=request.POST.get('assignedDoctorId'))
            patient=patient.save()
            my_patient_group = Group.objects.get_or_create(name='PATIENT')
            my_patient_group[0].user_set.add(user)
            logger.debug("This is a debug message")
        else: 
            logger.debug("This is a debug message")
        return HttpResponseRedirect('patientlogin')
    return render(request,'hospital/patientsignup.html',context=mydict)

models.py

class Patient(models.Model):
    user=models.OneToOneField(User,on_delete=models.CASCADE)
    address = models.CharField(max_length=40,null=True,blank=True,default=None)
   mobile = models.CharField(max_length=20,null=True,blank=True,default=None)
    assignedDoctorId = models.ForeignKey(Doctor, on_delete=models.CASCADE)
    admitDate=models.DateField(auto_now=True)
    status=models.BooleanField(default=False)
    @property
    def get_name(self):
        return self.user.first_name+" "+self.user.last_name
    @property
    def get_id(self):
        return self.user.id
    def __str__(self):
        return self.user.first_name

error:

Environment:


Request Method: POST
Request URL: http://127.0.0.1:8000/admin-add-patient

Django Version: 5.1.4
Python Version: 3.13.1
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'hospital',
 'widget_tweaks']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback (most recent call last):
  File "C:\Users\denis\Desktop\hospitalmanagement-django5\.venv\Lib\site-packages\django\core\handlers\exception.py", line 55, in inner
    response = get_response(request)
               ^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\denis\Desktop\hospitalmanagement-django5\.venv\Lib\site-packages\django\core\handlers\base.py", line 197, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\denis\Desktop\hospitalmanagement-django5\.venv\Lib\site-packages\django\contrib\auth\decorators.py", line 60, in _view_wrapper
    return view_func(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\denis\Desktop\hospitalmanagement-django5\.venv\Lib\site-packages\django\contrib\auth\decorators.py", line 60, in _view_wrapper
    return view_func(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\hospitalmanagement-django5\hospital\views.py", line 360, in admin_add_patient_view
    patient.assignedDoctorId=request.POST.get('assignedDoctorId')
    ^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\denis\Desktop\hospitalmanagement-django5\.venv\Lib\site-packages\django\db\models\fields\related_descriptors.py", line 287, in __set__
    raise ValueError(
    ^

Exception Type: ValueError at /admin-add-patient
Exception Value: Cannot assign "'5'": "Patient.assignedDoctorId" must be a "Doctor" instance.

many many thanks for your big help

Again, I don’t understand why you have this assignment statement in your view, or why you think you need it here.

You do need to ensure that all required fields of both models are present in their forms. (You don’t have assignedDoctorId in in the fields definition for the form.)

The patient object is an instance of Patient since PatientForm is a ModelForm based on that model and has the assignedDoctorId field in the form defined as a ModelChoiceField with a reference to Doctor.

(And, you are still not handling the situation where either form is invalid, which is going to hide a lot of potential problems.)

thank you

I add assignedDoctorId in field list and remove

patient.assignedDoctorId=Doctor.objects.get(id=request.POST.get('assignedDoctorId'))

but error occurs…i don’t understand how to associate patient to its doctor

secondly how can i add checks for validation?

i’m really sorry for this my difficulty…

If the form and fields are created correctly, you don’t need to do that manually - that’s part of the form processing.

Ahh, also noticed that you’re submitting two different Django forms in the same HTML form - when you do this, you need to ensure you use the prefix attribute on the forms to ensure Django matches the submitted data to the right forms.

Side note: When you’re asking for follow-up assistance, please post the new code, don’t just describe it as something you’ve done - there’s always the possibility that what you did was not correct.

Also, when making a reference to an error you are receiving, always post the error with the traceback.

What specifically are you looking to check beyond the standard validation tests?
(Also, this appears that it may be a different question than what we’re trying to answer here - if so, I’d like to stay focused on this issue before moving on to a different subject to avoid confusion in this thread.)

model.py

class Doctor(models.Model):
    user=models.OneToOneField(User,on_delete=models.CASCADE)
    address = models.CharField(max_length=40,null=True,blank=True, default=None)
    mobile = models.CharField(max_length=20,null=True,blank=True,default=None)
    department= models.CharField(max_length=50,choices=departments,default='Orthopedic')
    status=models.BooleanField(default=True)
    @property
    def get_name(self):
        return self.user.first_name+" "+self.user.last_name
    @property
    def get_id(self):
        return self.user.id
    def __str__(self):
        return "{} ({})".format(self.user.first_name,self.department)



class Patient(models.Model):
    user=models.OneToOneField(User,on_delete=models.CASCADE)
    address = models.CharField(max_length=40,null=True,blank=True,default=None)
    mobile = models.CharField(max_length=20,null=True,blank=True,default=None)
    assignedDoctorId = models.ForeignKey(Doctor, on_delete=models.CASCADE)
    admitDate=models.DateField(auto_now=True)
    status=models.BooleanField(default=False)
    @property
    def get_name(self):
        return self.user.first_name+" "+self.user.last_name
    @property
    def get_id(self):
        return self.user.id
    def __str__(self):
        return self.user.first_name

forms.py

class DoctorUserForm(forms.ModelForm):
    class Meta:
        model=User
        fields=['first_name','last_name','username','password']
        widgets = {
        'password': forms.PasswordInput()
        }
class DoctorForm(forms.ModelForm):
    class Meta:
        model=models.Doctor
        fields=['address','mobile','department','status']

class PatientUserForm(forms.ModelForm):
    class Meta:
        model=User
        fields=['first_name','last_name','username','password']
        widgets = {
        'password': forms.PasswordInput()
        }

class PatientForm(forms.ModelForm):
    assignedDoctorId=forms.ModelChoiceField(queryset=models.Doctor.objects.all().filter(status=True),empty_label="Name and Department", to_field_name="id")
    class Meta:
        model=models.Patient
        fields=['address','mobile','assignedDoctorId','status']

view.py


def doctor_signup_view(request):
    userForm=forms.DoctorUserForm()
    doctorForm=forms.DoctorForm()
    mydict={'userForm':userForm,'doctorForm':doctorForm}
    if request.method=='POST':
        userForm=forms.DoctorUserForm(request.POST,prefix=userForm)
        doctorForm=forms.DoctorForm(request.POST,request.FILES,prefix=doctorForm)
        if userForm.is_valid() and doctorForm.is_valid():
            user=userForm.save()
            user.set_password(user.password)
            user.save()
            doctor=doctorForm.save(commit=False)
            doctor.user=user
            doctor=doctor.save()
            my_doctor_group = Group.objects.get_or_create(name='DOCTOR')
            my_doctor_group[0].user_set.add(user)
        return HttpResponseRedirect('doctorlogin')
    return render(request,'hospital/doctorsignup.html',context=mydict)


def patient_signup_view(request):
    userForm=forms.PatientUserForm()
    patientForm=forms.PatientForm()
    mydict={'userForm':userForm,'patientForm':patientForm}
    if request.method=='POST':
        userForm=forms.PatientUserForm(request.POST,prefix=userForm)
        patientForm=forms.PatientForm(request.POST,request.FILES,prefix=patientForm)
        if userForm.is_valid() and patientForm.is_valid():
            user=userForm.save()
            user.set_password(user.password)
            user.save()
            patient=patientForm.save(commit=False)
            patient.user=user
            patient=patient.save()
            my_patient_group = Group.objects.get_or_create(name='PATIENT')
            my_patient_group[0].user_set.add(user)
            logger.debug("This is a debug message")
        else: 
            logger.debug("This is a debug message")
        return HttpResponseRedirect('patientlogin')
    return render(request,'hospital/patientsignup.html',context=mydict)

error

Environment:


Request Method: POST
Request URL: http://127.0.0.1:8000/admin-add-patient

Django Version: 5.1.4
Python Version: 3.13.1
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'hospital',
 'widget_tweaks']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback (most recent call last):
  File "C:\Users\denis\Desktop\hospitalmanagement-django5\.venv\Lib\site-packages\django\core\handlers\exception.py", line 55, in inner
    response = get_response(request)
               ^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\denis\Desktop\hospitalmanagement-django5\.venv\Lib\site-packages\django\core\handlers\base.py", line 197, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\denis\Desktop\hospitalmanagement-django5\.venv\Lib\site-packages\django\contrib\auth\decorators.py", line 60, in _view_wrapper
    return view_func(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\denis\Desktop\hospitalmanagement-django5\.venv\Lib\site-packages\django\contrib\auth\decorators.py", line 60, in _view_wrapper
    return view_func(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\hospitalmanagement-django5\hospital\views.py", line 360, in admin_add_patient_view
    patient.assignedDoctorId=request.POST.get('assignedDoctorId')
    ^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\denis\Desktop\hospitalmanagement-django5\.venv\Lib\site-packages\django\db\models\fields\related_descriptors.py", line 287, in __set__
    raise ValueError(
    ^

Exception Type: ValueError at /admin-add-patient
Exception Value: Cannot assign "'3'": "Patient.assignedDoctorId" must be a "Doctor" instance.

many many thanks
I will try solve check validation alone where I solve how to associate each patient to its doctor.

Something still doesn’t match up here.

Your error message highlights this function:

But that’s not the name of the view you’re showing here (patient_signup_view).

Also, the form prefix is a string, not an object or a form class. (See the examples in the reference doc.)

thank you for your help…I correct mistake in the correct function