【问题标题】:How to get data from one Django model to query another model within a template loop?如何从一个 Django 模型中获取数据以在模板循环中查询另一个模型?
【发布时间】:2019-10-04 11:13:14
【问题描述】:

我的 Django 应用程序有两个模型“项目”和“颜色”,分别代表数据库表“项目”和“颜色”。 Django 模板“mytemplate.html”使用“for”循环呈现从数据库收集的数据,打印出带有属​​性的项目列表。

“items”表的字段之一是一个数字 id,对应于“colors”表中的文本字段。 目前,我可以显示所有项目及其名称和颜色数字 id 'cid'(参见下面的代码)。

但我需要在模板循环中打印项目的颜色名称而不是它的“cid”/“id”。实现这一目标的最有效方法是什么?我是否需要一个中间数据结构,改变我的数据库来定义一个外键 (items(cid) --> colors(id)),...?

我不确定是否要使用外键 (items(cid) --> colors(id)),因为在第一次插入项目时,“cid”可能是未定义的 (NULL)。

表格“项目”

+------+------+------+
| id   | cid  | name |
+------+------+------+
|  1   |   3  | barZ |
|  2   |   3  | barC |
|  3   |   1  | barE |
|  3   |   2  | barD |
|  4   |   1  | barA |
+------+------+------+

表格“颜色”

+------+---------+
| id   | name    | 
+------+---------+
|  1   |   red   | 
|  2   |   white | 
|  3   |   blue  | 
+------+---------+

models.py

from django.db import models

class Items(models.Model):
    cid = models.IntegerField(blank=True, null=True)
    name = models.TextField(blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'items'

class Colors(models.Model):
    name = models.TextField(blank=False, null=False)

    class Meta:
        managed = False
        db_table = 'colors'

views.py

from django.shortcuts import render
from .models import Items
from .models import Colors

def item_list(request):

    items = Items.objects.all().order_by('id')
    colors = Colors.objects.all().order_by('name')

    return render(request,'mytemplate.html',{
        'items': items, 
        'colors': colors  
    })

mytemplate.html

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Foos</title>
</head>
<body>
{% block page_content %}
<table>
{% for item in items %}
    <tr>
        <td>{{ items.name }}</td>
        <td>{{ items.cid }}</td>
    </tr>
{% endfor %}
</table>
{% endblock %}
</body>
</html>

【问题讨论】:

  • 在问题中包含您的models
  • @ans2human:说得好,完成了。关于实际问题的任何提示?

标签: python django python-3.x database


【解决方案1】:

您应该使用外键。该外键可以设置为nullable,因此在创建时将其设置为NULL 是没有问题的。

之后,可以通过执行 {{ items.color.name }} 之类的操作轻松地从模板中访问颜色

你可以找到更多关于django模型的外键here的信息。

【讨论】:

  • carlesgg97: 'colors' 表的 'id' 列在我当前的实现中不能为空,因此将 'cid' 定义为在 'items' 表中引用颜色(id)的外键会产生错误"ERROR 1005 (HY000): Can't create table 'mydb.#sql-573_19' (errno: 150). 'cid' 可以是未定义的,但 colors(id) 不能。
  • 我已经使它适用于声明如下的模型:pastebin.com/J8Zm970L。你是如何声明你的外键的?
  • 在原始 SQL 中:ALTER TABLE 项目添加外键(cid)引用颜色(id);
  • donmelchior:确保 Item.cid 列可以为空(不得将其声明为 NOT NULL 或 UNIQUE)。作为参考,你可以看看 django makemigrations 生成的 SQL create table 语句:pastebin.com/dhT8mYC3
【解决方案2】:

在这个特定的用例中,我不能使用外键在可空列(项目“cid”)和不可空列(颜色“id”)之间创建关系。

我使用稍后从模板调用的方法“get_color”直接在模型中创建了“items”表数据和“colors”表数据之间的关系:

models.py

from django.db import models

class Colors(models.Model):
    name = models.TextField(blank=False, null=False)

    class Meta:
        managed = False
        db_table = 'colors'

class Items(models.Model):
    cid = models.IntegerField(blank=True, null=True)
    name = models.TextField(blank=True, null=True)

    # New method to grap data from Colors model 
    def get_color(self):
        color_object = Colors.objects.get(id = self.cid)
        color = color_object.name
        return color

    class Meta:
        managed = False
        db_table = 'items'

views.py

from django.shortcuts import render
from .models import Items
from .models import Colors

def item_list(request):

    items = Items.objects.all().order_by('id')
    colors = Colors.objects.all().order_by('name')

    return render(request,'mytemplate.html',{
        'items': items
        # Note: Direct reference to 'colors' table is no longer needed here

    })

mytemplate.html

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Items</title>
</head>
<body>
{% block page_content %}
<table>
{% for item in items %}
    <tr>
        <td>{{ item.name }}</td>
        <!-- get_color method call from model Class instance -->
        <td>{{ item.get_color }}</td>
    </tr>
{% endfor %}
</table>
{% endblock %}
</body>
</html>

如前所述,在许多用例中,设置外键是一种最佳实践。但是上面显示的实现很有用,特别是如果您想执行附加数据转换。请注意,您不能直接将参数传递给模板调用中的方法'&lt;td&gt;{{ item.get_color }}&lt;/td&gt;'

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-16
    • 2018-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多