简体   繁体   中英

How to get a specific queryset in Django

I am building a hospital management app and I am currently building the Nurse's webpage. In that webpage, I would like the following to display: a list of all employed nurses, a list of their workshifts, and what departments they work for.

I am trying to get the department section to display but I keep getting an error "too many values to unpack (expected 2)".

What can I do so that the nurses' department shows?

Models.py

from django.db import models

# Create your models here.

#Work Related aka Department and Work Shift

class Department(models.Model):
    name = models.CharField(max_length=200, null=True, blank=True)

    def __str__(self):
        return self.name

class WorkShift(models.Model):
    name = models.CharField(max_length=200, null=True, blank=True)
    start_datetime = models.DateTimeField(null=True, blank=True)
    end_datetime = models.DateTimeField(null=True, blank=True)

    def __str__(self):
        return self.name 

#Personel Related aka Employees and Patients

class Doctor(models.Model):
    name = models.CharField(max_length=200, null=True, blank=True)
    email = models.CharField(max_length=200, null=True)
    phone = models.CharField(max_length=200, null=True)
    department = models.ForeignKey(Department, null=True, blank=True, on_delete=models.CASCADE)
    work_shift = models.OneToOneField(WorkShift, blank=True, null=True, on_delete=models.CASCADE)

    def __str__(self):
        return self.name

class Nurse(models.Model):
    name = models.CharField(max_length=200, null=True)
    email = models.CharField(max_length=200, null=True)
    phone = models.CharField(max_length=200, null=True)
    sector = models.ForeignKey(Department, null=True, blank=True, on_delete=models.CASCADE)
    reports_to = models.ForeignKey(Doctor, blank=True, null=True, on_delete=models.CASCADE)
    work_shift = models.OneToOneField(WorkShift, default="", blank=True, null=True, on_delete=models.CASCADE)
    
    def __str__(self):
         return self.name

class Patient(models.Model):
    STATUS = (
        ('Sick', 'Sick'),
        ('Healing', 'Healing'),
        ('Cured', 'Cured'),
        ('Deceased', 'Deceased'),
    )

    name = models.CharField(max_length=200, null=True, blank=True)
    description = models.TextField(blank=True, null=True)
    status = models.CharField(max_length=200, null=True, blank=True, choices=STATUS)
    department = models.ForeignKey(Department, default="", null=True, blank=True, on_delete=models.CASCADE)
    care = models.ForeignKey(Nurse, default="", blank=True, null=True, on_delete=models.CASCADE)
    date_created = models.DateTimeField(auto_now_add=True, blank=True, null=True)

    def __str__(self):
        return self.name

from django.shortcuts import render, redirect

Views.py

# Create your views here.
from django.shortcuts import render
from .models import Doctor, Nurse, Patient, Department, WorkShift
from django.http import HttpResponse
from .forms import DoctorForm, NurseForm, PatientForm

# Create your views here.
def index(request):
    patient = Patient.objects.all()
    nurse = Nurse.objects.all()
    doctor = Doctor.objects.all()
    department = Department.objects.all()

    total_patient = patient.count()
    sick = patient.filter(status='Sick').count()
    healing = patient.filter(status='Healing').count()
    cured = patient.filter(status='Cured').count()

    total_nurse = nurse.count()

    # if request.method == 'POST':
    #     form = 

    context = {
        'patient':patient, 'nurse':nurse,
        'doctor':doctor, 'total_patient':total_patient,
        'sick':sick, 'healing':healing, 'cured':cured,
        'total_nurse':total_nurse,
        'department':department
    }

    return render(request, 'lifesaver/index.html', context)

#All Patient Related

def patient(request):
    patient = Patient.objects.all()

    context = {'patient':patient}
    return render(request, 'lifesaver/patient.html', context)

def patient_add(request):

    patient = Patient.objects.all()
    form = PatientForm()

    if request.method == 'POST':
        form = PatientForm(request.POST)
        if form.is_valid():
            print("Patient Form is Valid")
            form.save()
        else:
            print("Patient Form is Invalid")
            print(form.errors)
        return redirect('patient')

    context = {'form':form,}
    return render(request, 'lifesaver/patient_add.html', context)

def patient_update(request, pk):

    patient = Patient.objects.get(id=pk)
    form = PatientForm(instance=patient)

    if request.method == 'POST':
        form = PatientForm(request.POST, instance=patient)
        if form.is_valid():
            print('Update completed')
            form.save()
            return redirect('patient')
        else:
            print('Update not completed')
            print(form.errors)
            
    context = {'form':form}

    return render(request, 'lifesaver/patient_update.html', context)

#All Doctor Related

def doctor(request):

    doctor = Doctor.object.all()

    context = {}
    return render(request, 'lifesaver/doctor.html', context)

def doctor_add(request):
    
    doctor = Doctor.object.all()
    form = DoctorForm()

    context = {'doctor':doctor, 'form':form}
    return render(request, 'lifesaver/doctor')

def doctor_update(request):

    doctor = Doctor.object.all()
    form = DoctorForm()

    context = {'doctor':doctor, 'form':form}

# Nurse Related

def nurse(request):
    nurse = Nurse.objects.all()
    workshift = WorkShift.objects.all()
    department = Nurse.objects.get('sector')

    context = {'nurse':nurse, 'workshift':workshift, 'department':department}
    return render(request, 'lifesaver/nurse.html', context)
    

def nurse_add(request):
    nurse = Nurse.objects.all()
    form = NurseForm()

    if request.method == 'POST':
        form = NurseForm(request.POST)
        if form.is_valid():
            print("Nurse Form is Valid")
            form.save()
        else:
            print("Nurse Form is Invalid")
            print(form.errors)
        return redirect('nurse')

    context = {'form':form,}
    return render(request, 'lifesaver/nurse_add.html', context)

def nurse_update(request):
    nurse = Nurse.objects.all()
    form = NurseForm()

    context = {}
    return render(request, 'lifesaver/nurse_update.html', context)

#Work Related

def department(request):
    department = Department.objects.all()

    context = {'department':department}
    return render(request, 'lifesaver/department.html', context)

Forms.py

from django import forms
from django.forms import ModelForm
from .models import Doctor, Nurse, Patient, Department, WorkShift
from django.contrib.auth.forms import UserCreationForm

class DoctorForm(forms.ModelForm):
    name = forms.CharField(widget = forms.TextInput(attrs = 
    {

            'placeholder': 'Add a New Doctor',
            'class': 'form-control'
    }
    ))

    department = forms.ModelChoiceField(queryset=Department.objects.all(), widget=forms.Select(attrs=
    {
            'class': 'selectpicker',
            'placeholder': 'Department', 
    }
    )) 

    class Meta:
        model = Doctor
        fields = ['name', 'department']

class NurseForm(forms.ModelForm):
    name = forms.CharField(widget = forms.TextInput(attrs = 
    {

            'placeholder': 'Add a New Nurse',
            'class': 'form-control'
    }
    ))

    class Meta:
        model = Nurse
        fields = ['name']

class PatientForm(ModelForm):
    name = forms.CharField(widget = forms.TextInput(attrs = 
    {

            'placeholder': 'Add a New Nurse',
            'class': 'form-control'
    }
    ))

    description = forms.CharField(widget = forms.TextInput(attrs =
    {
            'placeholder': "Describe the patient's symptoms",
            'class': 'form-control'
    }
    ))

    department = forms.ModelChoiceField(queryset=Department.objects.all(), widget=forms.Select(attrs=
    {
            'class': 'selectpicker',
            'placeholder': 'Select Department', 
    }
    )) 

    class Meta:
        model = Patient
        fields = ['name', 'description', 'department', 'care', 'status']

#Work Related

class WorkShiftForm(ModelForm):
        class Meta:
                model = WorkShift
                fields = '__all__'

Nurse.html

{% extends 'lifesaver/main.html' %}

{% block content %}

{% for nurse in nurse %}
    {{nurse.name}}
    {{nurse.report_to}}
    {{nurse.care}}
    {{nurse.work_shift}}
    {{department}}
{% endfor %}


{% endblock %}

值错误

you need to pass a field and a value, eg

  Nurse.objects.get('sector' = 'dentistry')

or if you want to display a specific nurses department you would use this in your template:

{{nurse.department.name}}

In models.py, Nurse object has field 'sector' which is a Foreign Key to a Department record. So part of the problem is you're trying to output the wrong field name in your template as there is no actual department field defined on Nurse model.

Try these edits to views.py: nurses = Nurse.objects.all() then in your context: context = {..., 'nurses': nurses, ...}

Then in nurse.html:

{% for nurse in nurses: %}
   ...
   {{ nurse.sector.name }}
{% endfor %}

That should at least get your nurse objects rendered in the template. But you have a potential issue in calling nurse.sector when that FK is defined in the Nurse model with null=True . So a better practice would be to define an accessor method in the Nurse model to check if sector is present before calling it's name , ie:

# in Nurse model
def department_name(self):
    if self.sector_id:
        return self.sector.name
    else:
        return '' # or some other default

Then you could edit nurse.html again replacing my code above with:

{% for nurse in nurses: %}
   ...
   {{ nurse.department_name }}
{% endfor %}

This is just scratching the surface of how you could handle this but it hopefully answers your question and prevents a common error once you make these edits.

You'll also probably want to look into Django QuerySet API's select_related() and prefetch_related() methods to avoid N+1 query issues that are possible in your current code. See here and here for more background.

So for example, to avoid N+1, instead of calling nurses = Nurse.objects.all() instead do nurses = Nurse.objects.select_related('sector').all() . That will do a join to the Department model on the FK. This answer to one of the above N+1 questions has more details.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM