Django prefetch_related over 3 models (one “relationship Model”

huangapple go评论110阅读模式
英文:

Django prefetch_related over 3 models (one "relationship Model"

问题

I'm trying to aggregate and Output Data from my Models to my HTML Page

Models.py

  1. from django.db import models
  2. from django.contrib import admin
  3. class ClientDB(models.Model):
  4. Hostname= models.CharField(max_length=50,primary_key=True)
  5. User= models.CharField(max_length=100)
  6. class VULDB(models.Model):
  7. VID=models.IntegerField(primary_key=True)
  8. CVELIST=models.CharField(max_length=50)
  9. CVSScore=models.FloatField(max_length=5)
  10. Serverity=models.CharField(max_length=25)
  11. Title=models.CharField(max_length=1000)
  12. Summary=models.CharField(max_length=1000)
  13. class ClientVULDB(models.Model):
  14. Hostname= models.ForeignKey(ClientDB, on_delete=models.CASCADE)
  15. VID=models.ForeignKey(VULDB, on_delete=models.CASCADE)
  16. Path=models.CharField(max_length=1000)
  17. isActive=models.BooleanField(default=True)
  18. class Meta:
  19. constraints = [
  20. models.UniqueConstraint(
  21. fields=['Hostname', 'VID'], name='unique_migration_host_combination'
  22. )
  23. ]

I would like to create a view that Output and aggregate Data in the Model to my HTML Template. I need help how I can aggregate (and put it in a Queryset?) the data like in the Screenshot

I've got two Querysets which Query the Models:

q1=VULDB.objects.filter().values_list('Title','clientvuldb__Hostname')
q2=ClientDB.objects.filter().values_list('Hostname', 'Benutzer', 'clientvuldb__VID')

The Output is as follows:

<QuerySet [('Test-VUL', 'Host2'), ('Test-VUL2', 'Host2'), ('Test-VUL3', 'Host1'), ('Test-Vul4', 'Host2')]>

<QuerySet [('Host1', 'User1', 1), ('Host2', 'User2', 1)]

I would like to render

Host1, Test-VUL3

Host2, Test-VUL, Test-VUL2, Test-VUL3

英文:

I'm trying to aggregate and Output Data from my Models to my HTML Page

Models.py

  1. from django.db import models
  2. from django.contrib import admin
  3. class ClientDB(models.Model):
  4. Hostname= models.CharField(max_length=50,primary_key=True)
  5. User= models.CharField(max_length=100)
  6. class VULDB(models.Model):
  7. VID=models.IntegerField(primary_key=True)
  8. CVELIST=models.CharField(max_length=50)
  9. CVSScore=models.FloatField(max_length=5)
  10. Serverity=models.CharField(max_length=25)
  11. Title=models.CharField(max_length=1000)
  12. Summary=models.CharField(max_length=1000)
  13. class ClientVULDB(models.Model):
  14. Hostname= models.ForeignKey(ClientDB, on_delete=models.CASCADE)
  15. VID=models.ForeignKey(VULDB, on_delete=models.CASCADE)
  16. Path=models.CharField(max_length=1000)
  17. isActive=models.BooleanField(default=True)
  18. class Meta:
  19. constraints = [
  20. models.UniqueConstraint(
  21. fields=[&#39;Hostname&#39;, &#39;VID&#39;], name=&#39;unique_migration_host_combination&#39; # legt
  22. )
  23. ]

I would like to create a view that Output and aggregate Data in the Model to my HTML Template. I need help how I can aggregate (and put it in an Queryset?) the data like in the Screenshot

I've got two Querysets which Query the Models:

  1. q1=VULDB.objects.filter().values_list(&#39;Title&#39;,&#39;clientvuldb__Hostname&#39;)
  2. q2=ClientDB.objects.filter().values_list(&#39;Hostname&#39;, &#39;Benutzer&#39;, &#39;clientvuldb__VID&#39;)

The Output is as follows:

<QuerySet [('Test-VUL', 'Host2'),
('Test-VUL2', 'Host2'),
('Test-VUL3', 'Host1'),
('Test-Vul4', 'Host2')]>

<QuerySet [ ('Host1', 'User1', 1),
('Host2', 'User2', 1)]

I would like to render

Host1, Test-VUL3

Host2, Test-VUL, Test-VUL2, Test-VUL3

答案1

得分: 1

不要使用 .values(..).values_list(..),它会侵蚀模型层。

使用以下方式:

  1. from django.db.models import Prefetch
  2. qs = VULDB.objects.prefetch_related(
  3. Prefetch('clientvuldb_set', ClientVULDB.objects.select_related('VID'))
  4. )

在模板中,使用以下方式进行渲染:

  1. <ul>
  2. {% for item in qs %}
  3. <li>{{ item.Hostname }}</li>
  4. <ul>
  5. {% for subitem in item.clientvuldb_set.all %}
  6. <li>{{ subitem.VID.title }}</li>
  7. {% endfor %}
  8. </ul>
  9. {% endfor %}
  10. </ul>

注意: 通常,Django 模型中字段的命名应该使用 snake_case,而不是 PascalCase,所以应该是:title 而不是 Title

注意: 模型通常不应该带有 Db 后缀。模型不是表,它存储在关系数据库中作为表,但即使在那里,它还有额外的逻辑,如验证器、管理器等。

英文:

Don't use .values(..) or .values_list(..), it will erode the model layer.

work with:

<pre><code>from django.db.models import Prefetch

qs = VULDB.objects.prefetch_related(
<b>Prefetch(</b>'clientvuldb_set', ClientVULDB.objects.select_related('VID')<b>)</b>
)</code></pre>

in the template, render with:

<pre><code>&lt;ul&gt;
{% for item in qs %}
&lt;li&gt;{{ qs.Hostname }}</li>
&lt;ul&gt;
{% for subitem in <b>item.clientvuldb_set.all</b> %}
&lt;li&gt;{{ subitem.VID.Title }}&lt;/li&gt;
{% endfor %}
&lt;/ul&gt;
{% endfor %}
&lt;/ul&gt;</code></pre>


> Note: normally the name of the fields in a Django model are written in snake_case, not PascalCase, so it should be: title instead of <s>Title</s>.


> Note: Models normally have no Db suffix. A model is not a table, it is stored in a relational database as a table, but even then it has extra logic like validators, managers, etc.

huangapple
  • 本文由 发表于 2023年5月6日 22:38:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/76189465.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定