Django - 在一页上检索 2 个独立查询集的数据
Django - Retrieve Data for 2 Separate Querysets On One Page
我正在使用 Django、PyCharm 2018.3.7、Python 3.7 和 Postgres。
不幸的是,我不明白如何在一个屏幕页面(Django 形式)上显示两个单独的查询集的结果,这两个查询集需要通过动态筛选请求 (GET) 传递的相同 ID。有一个 table/model (ASSIGNMENTS) 与另一个 table/model (PRODUCTS) 具有一对多关系。传递的 ID 是 ASSIGNMENTS.ID,它是 ASSIGNMENTS 的 PK 和 PRODUCTS 的 FK。
我没有尝试加入这两个查询集。我需要用户首先查看 ASSIGNMENT 的信息,然后在下面我希望他们看到属于该 ASSIGNMENT 的所有产品。
我不需要update/create数据,所以不需要POST。只想检索,GET,存在的数据。
下面是 models.py、views.py 和模板的代码。它仅适用于 ASSIGNMENTS。
MODELS.PY
class Assignments(models.Model):
id = models.DecimalField(db_column='ID', primary_key=True, max_digits=9, decimal_places=0)
name = models.CharField(db_column='NAME', unique=True, max_length=40)
def __str__(self):
return self.name + ' ' + '(' + '#' + str(self.id) + ')'
class Meta:
ordering = 'name',
db_table = 'ASSIGNMENTS'
class Products(models.Model):
id = models.DecimalField(db_column='ID', primary_key=True, max_digits=11, decimal_places=0)
assignment = models.ForeignKey(Assignments, models.DO_NOTHING, related_name='productsfor_assignment', db_column='ASSIGNMENT_ID', blank=True, null=True)
name = models.CharField(db_column='NAME', max_length=80)
def __str__(self):
return self.name + ' ' + '(' + '#' + str(self.id) + ')'
class Meta:
ordering = 'name',
db_table = 'PRODUCTS'
VIEWS.PY
def search_form(request):
return render(request, 'assignments/search_form.html')
def search(request):
if 'q' in request.GET and request.GET['q']:
q = request.GET['q']
assign = Assignments.objects.filter(id__icontains=q)
return render(request, 'assignments/search_results.html',
{'AssignmentsResults': assign, 'query': q})
else:
# if the query is empty, render the 'search_form html' template again.
# display an error message in that template. So, pass a template variable.
# 'search_form html' will check for the 'error' variable
return render(request, 'assignments/search_form.html', {'error': True})
模板'search_form.html'
{% extends "base.html" %}
{% block content %}
<br><br>
<h1> Assignment ID Search Form </h1>
<br><br>
{% if error %}
<p style="color: red;">Please submit a search term.</p>
{% endif %}
<form action="/search/" method="get">
<input type="text" name="q" placeholder="Enter ID here ...">
<input type="submit" value="Search">
</form>
<p>
Page last updated: {{ last_updated|date:'D d F Y' }}
</p>
{% endblock content %}
模板'search_results.html'
{% extends "base.html" %}
{% block content %}
<br><br>
<h1> Assignment ID Search Results</h1>
<p>You searched for: <strong>{{ query }}</strong></p>
{% if AssignmentsResults %}
<ul>
{% for assignments in AssignmentsResults %}
<li>
{{ assignments.id }}, {{ assignments.name }}
</li>
{% endfor %}
</ul>
{% else %}
<p>No assignments matched your search criteria.</p>
{% endif %}
{% endblock content %}
这是我最终放在一起以包含产品的内容(如下面失败的 views.py 和模板所示)。但是,它不起作用。
这是 失败的 VIEWS.PY
def search_form(request):
return render(request, 'assignments/search_form.html')
def search(request):
if 'q' in request.GET and request.GET['q']:
q = request.GET['q']
assign = Assignments.objects.filter(id__icontains=q)
prod = Products.objects.filter(assignment__icontains=q)
return render(request, 'assignments/search_results.html',
{'AssignmentsResults': assign, 'query': q})
return render(request, 'assignments/search_results.html',
'ProductsResults': prod, 'query': q)
else:
# if the query is empty, render the 'search_form html' template again.
# display an error message in that template. So, pass a template variable.
# 'search_form html' will check for the 'error' variable
return render(request, 'assignments/search_form.html', {'error': True})
这是失败的模板代码'search_results.html
{% extends "base.html" %}
{% block content %}
<br><br>
<h1> Assignment ID Search Results</h1>
<p>You searched for: <strong>{{ query }}</strong></p>
{% if AssignmentsResults %}
<ul>
{% for assignments in AssignmentsResults %}
<li>
{{ assignments.id }}, {{ assignments.name }}
</li>
{% endfor %}
</ul>
<p> These are the Products attached to the Assignment.</p>
{% if ProductsResults %}
<ul>
{% for products in ProductsResults %}
<li>
{{ products.assignment }}, {{ products.name }}
</li>
{% endfor %}
</ul>
{% else %}
<p> No products for this assignment exist.</p>
{% endif %}
{% else %}
<p>No assignments matched your search criteria.</p>
{% endif %}
{% endblock content %}
我按照 Nigel George 的 'Build a website with Django 2, updated for Django 2.2' 创建了这个项目。我看过几个 youtube 教学视频并阅读了关于 Whosebug 的问题。 (这只是一对。)
How to combine two or more querysets in a Django view?
Django: Add queryset to inlineformsets
Django nested QuerySets
InlineFormSet with queryset of different model
但是,none 他们已经能够帮助我解决在一个表单上呈现 2 个单独的查询集结果的问题。
我非常感谢您提供的任何建议和帮助。
谢谢
好的,让我们看看。如果您只想显示 search_results.html 中的信息,我建议您按如下方式稍微重构您的查询。
(我会尽可能多地清理奇怪的东西(例如有两个连续的 return 语句)来说明我的观点)
views.py:
from django.shortcuts import render, redirect
from django.urls import reverse
def search(request):
q = request.GET.get('q', None)
if q:
assignments_qs = Assignments.objects.filter(id__icontains=q) \
.prefetch_related('productsfor_assignment')
context_data = {'assignments': assignments_qs}
return render(request, 'assignments/search_results.html', context_data)
else:
return redirect(reverse('search_form', kwargs={'error': True}))
def search_form(request, error=False):
return render(request, 'assignments/search_form.html', {'error': error})
search_results.html
{% if assignments %}
<ul>
{% for assignment in assignments %}
<li>
{{ assignment.id }}, {{ assignment.name }}
</li>
{% if assignment.productsfor_assignment.exists %}
<p> These are the Products attached to the Assignment.</p>
<ul>
{% for product in assignment.productsfor_assignment.all %}
<li>
{{ product.assignment }}, {{ product.name }}
</li>
{% endfor %}
</ul>
{% endif %}
{% endfor %}
</ul>
{% else %}
<p>No assignments matched your search criteria.</p>
{% endif %}
考虑到你目前拥有的东西,我认为这是实现你想要的最好和最相似的方法。
我正在使用 Django、PyCharm 2018.3.7、Python 3.7 和 Postgres。
不幸的是,我不明白如何在一个屏幕页面(Django 形式)上显示两个单独的查询集的结果,这两个查询集需要通过动态筛选请求 (GET) 传递的相同 ID。有一个 table/model (ASSIGNMENTS) 与另一个 table/model (PRODUCTS) 具有一对多关系。传递的 ID 是 ASSIGNMENTS.ID,它是 ASSIGNMENTS 的 PK 和 PRODUCTS 的 FK。
我没有尝试加入这两个查询集。我需要用户首先查看 ASSIGNMENT 的信息,然后在下面我希望他们看到属于该 ASSIGNMENT 的所有产品。
我不需要update/create数据,所以不需要POST。只想检索,GET,存在的数据。
下面是 models.py、views.py 和模板的代码。它仅适用于 ASSIGNMENTS。
MODELS.PY
class Assignments(models.Model):
id = models.DecimalField(db_column='ID', primary_key=True, max_digits=9, decimal_places=0)
name = models.CharField(db_column='NAME', unique=True, max_length=40)
def __str__(self):
return self.name + ' ' + '(' + '#' + str(self.id) + ')'
class Meta:
ordering = 'name',
db_table = 'ASSIGNMENTS'
class Products(models.Model):
id = models.DecimalField(db_column='ID', primary_key=True, max_digits=11, decimal_places=0)
assignment = models.ForeignKey(Assignments, models.DO_NOTHING, related_name='productsfor_assignment', db_column='ASSIGNMENT_ID', blank=True, null=True)
name = models.CharField(db_column='NAME', max_length=80)
def __str__(self):
return self.name + ' ' + '(' + '#' + str(self.id) + ')'
class Meta:
ordering = 'name',
db_table = 'PRODUCTS'
VIEWS.PY
def search_form(request):
return render(request, 'assignments/search_form.html')
def search(request):
if 'q' in request.GET and request.GET['q']:
q = request.GET['q']
assign = Assignments.objects.filter(id__icontains=q)
return render(request, 'assignments/search_results.html',
{'AssignmentsResults': assign, 'query': q})
else:
# if the query is empty, render the 'search_form html' template again.
# display an error message in that template. So, pass a template variable.
# 'search_form html' will check for the 'error' variable
return render(request, 'assignments/search_form.html', {'error': True})
模板'search_form.html'
{% extends "base.html" %}
{% block content %}
<br><br>
<h1> Assignment ID Search Form </h1>
<br><br>
{% if error %}
<p style="color: red;">Please submit a search term.</p>
{% endif %}
<form action="/search/" method="get">
<input type="text" name="q" placeholder="Enter ID here ...">
<input type="submit" value="Search">
</form>
<p>
Page last updated: {{ last_updated|date:'D d F Y' }}
</p>
{% endblock content %}
模板'search_results.html'
{% extends "base.html" %}
{% block content %}
<br><br>
<h1> Assignment ID Search Results</h1>
<p>You searched for: <strong>{{ query }}</strong></p>
{% if AssignmentsResults %}
<ul>
{% for assignments in AssignmentsResults %}
<li>
{{ assignments.id }}, {{ assignments.name }}
</li>
{% endfor %}
</ul>
{% else %}
<p>No assignments matched your search criteria.</p>
{% endif %}
{% endblock content %}
这是我最终放在一起以包含产品的内容(如下面失败的 views.py 和模板所示)。但是,它不起作用。
这是 失败的 VIEWS.PY
def search_form(request):
return render(request, 'assignments/search_form.html')
def search(request):
if 'q' in request.GET and request.GET['q']:
q = request.GET['q']
assign = Assignments.objects.filter(id__icontains=q)
prod = Products.objects.filter(assignment__icontains=q)
return render(request, 'assignments/search_results.html',
{'AssignmentsResults': assign, 'query': q})
return render(request, 'assignments/search_results.html',
'ProductsResults': prod, 'query': q)
else:
# if the query is empty, render the 'search_form html' template again.
# display an error message in that template. So, pass a template variable.
# 'search_form html' will check for the 'error' variable
return render(request, 'assignments/search_form.html', {'error': True})
这是失败的模板代码'search_results.html
{% extends "base.html" %}
{% block content %}
<br><br>
<h1> Assignment ID Search Results</h1>
<p>You searched for: <strong>{{ query }}</strong></p>
{% if AssignmentsResults %}
<ul>
{% for assignments in AssignmentsResults %}
<li>
{{ assignments.id }}, {{ assignments.name }}
</li>
{% endfor %}
</ul>
<p> These are the Products attached to the Assignment.</p>
{% if ProductsResults %}
<ul>
{% for products in ProductsResults %}
<li>
{{ products.assignment }}, {{ products.name }}
</li>
{% endfor %}
</ul>
{% else %}
<p> No products for this assignment exist.</p>
{% endif %}
{% else %}
<p>No assignments matched your search criteria.</p>
{% endif %}
{% endblock content %}
我按照 Nigel George 的 'Build a website with Django 2, updated for Django 2.2' 创建了这个项目。我看过几个 youtube 教学视频并阅读了关于 Whosebug 的问题。 (这只是一对。)
How to combine two or more querysets in a Django view?
Django: Add queryset to inlineformsets
Django nested QuerySets
InlineFormSet with queryset of different model
但是,none 他们已经能够帮助我解决在一个表单上呈现 2 个单独的查询集结果的问题。
我非常感谢您提供的任何建议和帮助。 谢谢
好的,让我们看看。如果您只想显示 search_results.html 中的信息,我建议您按如下方式稍微重构您的查询。 (我会尽可能多地清理奇怪的东西(例如有两个连续的 return 语句)来说明我的观点)
views.py:
from django.shortcuts import render, redirect
from django.urls import reverse
def search(request):
q = request.GET.get('q', None)
if q:
assignments_qs = Assignments.objects.filter(id__icontains=q) \
.prefetch_related('productsfor_assignment')
context_data = {'assignments': assignments_qs}
return render(request, 'assignments/search_results.html', context_data)
else:
return redirect(reverse('search_form', kwargs={'error': True}))
def search_form(request, error=False):
return render(request, 'assignments/search_form.html', {'error': error})
search_results.html
{% if assignments %}
<ul>
{% for assignment in assignments %}
<li>
{{ assignment.id }}, {{ assignment.name }}
</li>
{% if assignment.productsfor_assignment.exists %}
<p> These are the Products attached to the Assignment.</p>
<ul>
{% for product in assignment.productsfor_assignment.all %}
<li>
{{ product.assignment }}, {{ product.name }}
</li>
{% endfor %}
</ul>
{% endif %}
{% endfor %}
</ul>
{% else %}
<p>No assignments matched your search criteria.</p>
{% endif %}
考虑到你目前拥有的东西,我认为这是实现你想要的最好和最相似的方法。