Home > database >  AttributeError: 'NoneType' object has no attribute 'aptTime' in Django
AttributeError: 'NoneType' object has no attribute 'aptTime' in Django

Time:09-05

I have an appointment model for patient to book appointment with a doctor, i used a custom user model for both doctor and patients, using is_staff and is_patient to differentiate them...

class Appointment(models.Model):
   
    doctor = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='staff',
                               on_delete=models.SET_NULL, null=True)
    patient = models.ForeignKey(settings.AUTH_USER_MODEL, related_name=' ', on_delete=models.SET_NULL, null=True)
    aptTime = models.DateTimeField(blank=True, null=True)
    pending_approval = models.BooleanField(default=True, null=True)
    approved = models.BooleanField(default=False, null=True)

in my views.py i am trying to set the patient to request.user and doctor to the context i passed through the url, so i have the form_valid method to create appointment like this...

class AppointmentCreateView(CreateView):
    model = Appointment
    fields = ['aptTime']
    template_name = 'patients/Appointment-Createview.html'
    

    def form_valid(self, form, *args, **kwargs):
        form.instance.doctor = self.kwargs['pk'] #TODO change to doctor instance
        form.instance.aptTime = self.object.aptTime
        form.instance.patient = self.request.user
        form.save()

i got an error saying ValueError: Cannot assign "1": "Appointment.doctor" must be a "User" instance. Internal Server Error: /patient/Appointment-Create/1/ After searching around SO i was able to change my code to...

...Some code...

    def form_valid(self, form, *args, **kwargs):
        User = get_user_model()
        doc = User.objects.get(id=self.kwargs['pk'])
        form.instance.doctor = doc #TODO change to doctor instance
        form.instance.aptTime = self.object.aptTime
        form.instance.patient = self.request.user
        form.save()

   

now i'm getting a new error saying

form.instance.aptTime = self.object.aptTime
AttributeError: 'NoneType' object has no attribute 'aptTime'

I am using a model form, i don't understand why i'm getting this error. Someone please help me out.

CodePudding user response:

A CreateView has no self.object, this is always assigned None. You do not have to access this anyway, since this is already assigned to the object wrapped in the form, so:

from django.contrib.auth.mixins import LoginRequiredMixin


class AppointmentCreateView(LoginRequiredMixin, CreateView):
    model = Appointment
    fields = ['aptTime']
    template_name = 'patients/Appointment-Createview.html'

    def form_valid(self, form):
        form.instance.doctor_id = self.kwargs['pk']
        form.instance.patient = self.request.user
        return super().form_valid(form)

Your Appointment model however seems a bit odd. For example why not work with a nullable field approved that is NULL/None if it is not yet approved, True if the doctor approved, and False if the doctor rejected, this is probably better since otherwise the pending_approval can be False whereas approved can still be None resulting in a state that at least seems illogical:

class Appointment(models.Model):
    doctor = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        related_name='appointments',
        on_delete=models.SET_NULL,
        null=True,
    )
    patient = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        related_name=' ',
        on_delete=models.SET_NULL,
        null=True,
    )
    apt_time = models.DateTimeField()
    approved = models.BooleanField(default=None, null=True)

Note: You can limit views to a class-based view to authenticated users with the LoginRequiredMixin mixin [Django-doc].


Note: normally the name of the fields in a Django model are written in snake_case, not PascalCase, so it should be: apt_time instead of aptTime.

  • Related