我正在尝试在单个 html 表中渲染 3 个模型的数据。我尝试了几次错误但失败了。下面是我的代码。工作站、打印机和笔记本电脑具有外部站点 ID。我想按站点列出所有工作站、笔记本电脑和打印机过滤器。
下面是我的代码:
Models:
class Site(models.Model):
site_name = models.CharField(max_length=30, blank=True, null=True, verbose_name="Site Name")
site_address = models.CharField(max_length=30, blank=True, null=True, verbose_name="Site Address")
def __str__(self):
return self.site_name
class Workstation(models.Model):
name = models.CharField(max_length=30, blank=True, null=True, verbose_name="Workstation Name")
serial = models.CharField(max_length=30, blank=True, null=True, verbose_name="Serial")
workstation_model = models.CharField(max_length=30, blank=True, null=True, verbose_name="Workstation Model")
sitename = models.ForeignKey(Site, on_delete=models.SET_NULL, blank=True, null=True, verbose_name="Site")
def __str__(self):
return self.name
class Laptop(models.Model):
name = models.CharField(max_length=30, blank=True, null=True, verbose_name="Laptop Name")
serial = models.CharField(max_length=30, blank=True, null=True, verbose_name="Serial")
laptop_model = models.CharField(max_length=30, blank=True, null=True, verbose_name="Laptop Model")
sitename = models.ForeignKey(Site, on_delete=models.SET_NULL, blank=True, null=True, verbose_name="Site")
def __str__(self):
return self.name
class Printer(models.Model):
name = models.CharField(max_length=30, blank=True, null=True, verbose_name="Printer Name")
serial = models.CharField(max_length=30, blank=True, null=True, verbose_name="Serial")
printer_model = models.CharField(max_length=30, blank=True, null=True, verbose_name="Printer Model")
sitename = models.ForeignKey(Site, on_delete=models.SET_NULL, blank=True, null=True, verbose_name="Site")
def __str__(self):
return self.name
URL:
urlpatterns = [
path('', views.SiteView.as_view(), name='site'),
path('report/<sitename>', views.ReportView.as_view(), name='reportview'),
]
Template 1: Site List
<table>
<tr>
<th>Site</th>
<th>Address</th>
</tr>
{% for site in site_list %}
<tr>
<td><a href="{% url 'reportview' site.site_name %}">{{ site.site_name }}</a></td>
<td>{{ site.site_address }}</td>
</tr>
{% endfor %}
</table>
Template 2: Report equipment by site
<table>
<tr>
<th>Device</th>
<th>Serial</th>
</tr>
{% for item in site %}
<tr>
<td>{{ item.name }}</td>
<td>{{ item.serial }}</td>
</tr>
{% endfor %}
</table>
View for template 1: Successful output:
class SiteView(ListView):
model = Site
template_name = "mytestapp/site.html"
View for template 2: Failed
class ReportView(TemplateView):
template_name = "mytestapp/report.html"
def post(self, request):
site = request.POST["site"]
context = super().get_context_data(request)
context["site"] = Workstation.objects.get(sitename=site)
context["site"] = Laptop.objects.get(sitename=site)
context["site"] = Printer.objects.get(sitename=site)
return context
我正在尝试按站点在单表过滤器中列出工作站、笔记本电脑和打印机。示例输出: 图片
您本质上是在寻找一个联合,按站点名称过滤所有三个模型,然后将它们联合在一起。确保根据您的要求更改站点名称。
queries = []
for model in [Printer, Laptop, Workstation]:
queries.append(
model.objects.filter(sitename=1)
.values("name", "serial")
)
p, l, w = queries
print(p)
plw = p.union(l, w, all=True)
<QuerySet [{'name': 'Epson', 'serial': '2'}, {'name': 'printer1', 'serial': '23'}, {'name': 'Asus', 'serial': '1'}, {'name': 'Dell', 'serial': '56'}, {'name': 'Tas', 'serial': '1'}, {'name': 'WS2', 'serial': '234'}]>
Django 在联合查询中没有提供太多控制,因此如果您需要更多控制,您可能需要使用原始查询。或者您可以单独查询所有 3 个模型,然后使用 itertools.chain 将它们链接在一起
from itertools import chain
print(list(chain(*queries)))