AttributeError: объект 'NoneType' не имеет атрибута 'aptTime' в Django
У меня есть модель записи на прием к врачу для пациента, я использовал пользовательскую модель пользователя для врача и пациента, используя is_staff и is_patient для их разграничения...
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)
В моем views.py я пытаюсь установить пациента в request.user и врача в контекст, который я передал через url, поэтому у меня есть метод form_valid для создания записи на прием следующим образом...
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()
я получил ошибку, говорящую ValueError: Cannot assign "1": "Appointment.doctor" must be a "User" instance. Internal Server Error: /patient/Appointment-Create/1/.
После поиска в SO я смог изменить свой код на...
...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()
теперь я получаю новую ошибку, говорящую
form.instance.aptTime = self.object.aptTime
AttributeError: 'NoneType' object has no attribute 'aptTime'
Я использую модель формы, я не понимаю, почему я получаю эту ошибку. Кто-нибудь, пожалуйста, помогите мне.
А CreateView не имеет self.object, ему всегда присваивается None. Вам не нужно обращаться к нему в любом случае, так как он уже присвоен объекту, обернутому в форму, так:
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)
Ваша Appointment модель, однако, кажется немного одним. Например, почему бы не работать с нулевым полем approved, которое является NULL/None, если оно еще не одобрено, True, если доктор одобрил, и False, если доктор отклонил, это, вероятно, лучше, поскольку в противном случае pending_approval может быть False, в то время как approved все еще может быть None, что приводит к состоянию, которое, по крайней мере, кажется нелогичным:
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
LoginRequiredMixinmixin [Django-doc].
Примечание: обычно имена полей в модели Django записываются в snake_case, а не PascalCase, поэтому должно быть:
apt_timeвместо.aptTime