Проблема получения данных с помощью набора QuerySet модели с иностранными ключами (Django)
Я практикуюсь в создании django. Я нашел репо и отредактировал под себя. Когда я дошел до получения данных из моделей с foreignkey, я получаю запрос вместо данных. Я думаю, что моя функция немного спагетти или мой файл шаблона. Полный репо находится здесь https://github.com/eseymenler/demo2
Вот вывод моих кодов. Первый красный квадрат - это запрос, но я хочу, чтобы второй красный квадрат имел данные.
Имя пациента: {{ имя пациента }}
Проблема со здоровьем пациента: {{ зонд }}
.
Рост пациента: {{ vital }}
.
Статус курения пациента: {{ social }}
Первые данные {{ имя пациента }} очень хороши для меня. Это то, что я хочу. Но когда я пишу {{ prob.problem }}, это ничего мне не дает. Так где же моя ошибка. Но также, когда я делаю цикл for, как здесь, я получаю данные, которые мне нужны. Как я могу это исправить?
{% for y in prob %}
{{ y.problem }}
{% endfor %}
И мой views.py
@login_required()
def patienttumbilgiListView(request, id):
patient = Patient.objects.get(aadhaarId = id)
prob = ProblemList.objects.filter(patient = patient)
vital = VitalSign.objects.filter(patient = patient)
social = SocialHistory.objects.filter(patient = patient)
return render(
request, 'patient_records/patient-problem-tum.html',
context={'prob': prob, 'vital': vital, 'social': social, 'patient': patient })
и файл моего шаблона
{% extends 'base.html' %}
{% load static %}
{% load bootstrap4 %}
{% load i18n %}
{% block title %}problem-list-view{% endblock title %}
{% block content %}
<div class="container">
Hasta Adı: {{ patient.name }}</br>
Hastanın Sağlık Problemi: {{ prob }}<br>
Hastanın Boyu: {{ vital }}<br>
Hastanın Sigara Kullanım Durumu: {{ social }} <br></div>
<br>
<br>
<div class="container">
<style type="text/css">
.tg {border-collapse:collapse;border-spacing:0;}
.tg td{border-color:black;border-style:solid;border-width:1px;font-family:Arial, sans-serif;font-size:14px;
overflow:hidden;padding:10px 5px;word-break:normal;}
.tg th{border-color:black;border-style:solid;border-width:1px;font-family:Arial, sans-serif;font-size:14px;
font-weight:normal;overflow:hidden;padding:10px 5px;word-break:normal;}
.tg .tg-0lax{text-align:left;vertical-align:top}
</style>
<table class="tg">
<thead>
<tr>
<th class="tg-0lax">Hasta Adı:</th>
<th class="tg-0lax">{{ patient.name }}</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tg-0lax">Hastanın Sağlık Problemi:</td>
<td class="tg-0lax">{% for y in prob %}<br> <br> {{ y.problem }}<br> <br> <br>{% endfor %}</td>
</tr>
<tr>
<td class="tg-0lax">Hastanın Boyu:</td>
<td class="tg-0lax">{% for x in vital %}<br> <br> {{ x.height }}<br> <br> <br>{% endfor %}</td>
</tr>
<tr>
<td class="tg-0lax">Sigara Kullanımı:</td>
<td class="tg-0lax">{% for item in social %}<br> <br><br> {{ item.tobacco_smoking_status }}<br> <br> <br>{% endfor %}</td>
</tr>
</tbody>
</table>
</div>
<br>
<br>
{% endblock %}
Roughly What You Had
Итак, ваш код таков:
@login_required()
def patienttumbilgiListView(request, id):
patient = Patient.objects.get(aadhaarId = id)
prob = ProblemList.objects.filter(patient = patient)
vital = VitalSign.objects.filter(patient = patient)
social = SocialHistory.objects.filter(patient = patient)
return render(
request, 'patient_records/patient-problem-tum.html',
context={'prob': prob, 'vital': vital, 'social': social, 'patient': patient })
{% for y in prob %}
{{y.problem}}
{% endfor %}
{% for x in vital %}
{{x.height}}
{% endfor %}
{% for item in social %}
{{item.tobacco_smoking_status}}
{% endfor %}
Несколько дружеских предложений
"id" является зарезервированным словом / функцией - я предлагаю изменить id
на возможно pid
в вашем коде.
Возвращать ошибку в представление - Вам не обязательно делать это изменение, но я думаю, что это хорошая идея, и даже может помочь в поиске неисправностей. Я имею в виду, что вы, вероятно, должны возвращать ошибку или что-то в этом графике, если вы не можете найти эти объекты с этими id
в вашей базе данных.
"get()" выбрасывает ошибку DoesNotExist, если id не найден - Вы должны поймать ошибку и вернуть ее в создаваемую консоль или сделать что-то подобное.
views.py
@login_required()
def patienttumbilgiListView(request, pid):
context = {}
try:
patient = Patient.objects.get(aadhaarId = pid)
except DoesNotExist:
context['error'] = f"Could not find patient with id '{pid}'."
else:
context['prob'] = ProblemList.objects.filter(patient=patient)
context['vital'] = VitalSign.objects.filter(patient=patient)
context['social'] = SocialHistory.objects.filter(patient=patient)
context['patient'] = patient
return render(request, 'patient_records/patient-problem-tum.html', context=context)
template.html
{% if error %}
{{error}}
{% endif %}
{% for y in prob %}
{{y.problem}}
{% empty %}
Could not find problems.
{% endfor %}
{% for x in vital %}
{{x.height}}
{% empty %}
Could not find vitals.
{% endfor %}
{% for item in social %}
{{item.tobacco_smoking_status}}
{% empty %}
Could not find socials.
{% endfor %}
Что такое ваша проблема и как ее решить
Я практикуюсь в создании django. Я нашел репо и отредактировал под себя. Когда я дошел до получения данных из моделей с иностранным ключом, я получил запрос вместо данных.
Основываясь на этой цитате, я предполагаю, что вы хотите узнать, почему данные возвращаются в виде набора запросов, а не как единичный результат. Из docs:
filter() всегда даст вам QuerySet, даже если запросу соответствует только один объект - в данном случае это будет QuerySet, содержащий один элемент. Если вы знаете, что есть только один объект, соответствующий вашему запросу, вы можете использовать метод get() на Manager, который возвращает объект напрямую:
one_entry = Entry.objects.get(pk=1)
.
Поэтому вы должны использовать цикл for в вашем template.html. Если вы не хотите его использовать, то вам следует предварительно обработать эти данные, либо используя get()
вместо filter()
, либо просто, в контексте, отправить элемент [0]
в шаблон из вашего представления.
Итак, чтобы пояснить, если вы хотите использовать {{prob.problem}}
в вашем шаблоне, вам нужно изменить ваше представление, чтобы сделать либо prob = ProblemList.objects.filter(patient = patient)[0]
, либо prob = ProblemList.objects.get(patient = patient)
. Если вы выберете первое, вам следует проверить длину (prob = prob[0] if len(prob) == 1 else None
), в противном случае, если вы выберете последнее, вам следует обернуть его предложением try, except, else
, как это сделано здесь:
try:
prob = ProblemList.objects.get(patient=patient)
except DoesNotExist:
context['error'] = "Could not find ProblemList."
print("Does Not Exist")
else:
context['prob'] = prob
Или вы можете просто использовать цикл for, который у вас уже есть, я не знаю, сколько записей вы ожидаете, что набор запросов будет иметь на пациента.
Если мне нужно что-то уточнить, пожалуйста, дайте мне знать.