[英]How to get a specific queryset in Django
I am building a hospital management app and I am currently building the Nurse's webpage.我正在构建一个医院管理应用程序,我目前正在构建 Nurse 的网页。 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)".我试图让部门部分显示,但我不断收到错误“太多值无法解包(预期 2)”。
What can I do so that the nurses' department shows?我该怎么做才能让护士科显示?
Models.py模型.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视图.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 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护士.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.在 models.py 中,护士 object 具有字段“部门”,这是部门记录的外键。 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.所以问题的一部分是你试图 output 模板中的错误字段名称,因为在 Nurse model 上没有定义实际的department
字段。
Try these edits to views.py: nurses = Nurse.objects.all()
then in your context: context = {..., 'nurses': nurses, ...}
尝试对views.py进行这些编辑: nurses = Nurse.objects.all()
然后在您的上下文中: context = {..., 'nurses': nurses, ...}
Then in nurse.html:然后在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
.但是,当在 Nurse model 中使用null=True
定义 FK 时,您在调用nurse.sector
时会遇到潜在问题。 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:因此,更好的做法是在 Nurse model 中定义一个访问器方法,以在调用它的name
之前检查sector
是否存在,即:
# 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:然后你可以编辑nurse.html 再次将我上面的代码替换为:
{% 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.您可能还需要查看Django QuerySet API 的 select_related select_related()
和prefetch_related()
方法,以避免当前代码中可能出现的 N+1 查询问题。 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()
.因此,例如,为了避免 N+1,不要调用nurses = Nurse.objects.all()
而不是调用nurse nurses = Nurse.objects.select_related('sector').all()
。 That will do a join to the Department model on the FK.这将加入 FK 上的 model 部门。 This answer to one of the above N+1 questions has more details.对上述 N+1 问题之一的此答案有更多详细信息。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.