简体   繁体   English

如何在 Django 中获取特定的查询集

[英]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.

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