在单个 HTML 表中列出多个模型的数据

问题描述 投票:0回答:1

我正在尝试在单个 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

我正在尝试按站点在单表过滤器中列出工作站、笔记本电脑和打印机。示例输出: 图片

Sample output

django django-models django-views django-templates
1个回答
0
投票

您本质上是在寻找一个联合,按站点名称过滤所有三个模型,然后将它们联合在一起。确保根据您的要求更改站点名称。

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)))
© www.soinside.com 2019 - 2024. All rights reserved.