Как получить данные из одной модели Django для запроса другой модели в цикле шаблона? - PullRequest
0 голосов
/ 04 октября 2019

В моем приложении Django есть две модели «Элементы» и «Цвета», представляющие таблицы базы данных «элементы» и «цвета». Шаблон Django «mytemplate.html» отображает данные, собранные из базы данных, с помощью цикла «for», распечатывая список элементов с их свойствами.

Одним из полей таблицы 'items' является числовой идентификатор, соответствующий текстовому полю в таблице 'colors'. В настоящее время я могу отображать все элементы с их названиями и цветным числовым идентификатором 'cid' (см. Код ниже).

Но мне нужно напечатать название цвета элемента вместо его 'cid' / 'id' в цикле шаблона. Какой самый эффективный способ добиться этого? Нужна ли мне промежуточная структура данных, изменить базу данных, чтобы определить внешний ключ (items (cid) -> colors (id)), ...?

Я не уверен, что хочу использоватьвнешний ключ (items (cid) -> colors (id)), потому что во время первой вставки элементов 'cid' может быть неопределенным (NULL).

Таблица 'items'

+------+------+------+
| 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>

Ответы [ 2 ]

1 голос
/ 04 октября 2019

Вы должны использовать внешний ключ. Этот внешний ключ может быть установлен как nullable , поэтому его установка в NULL при создании не является проблемой.

После этого к цвету можно легко получить доступ из шаблона, выполнив что-то вроде{{ items.color.name }}

Более подробную информацию о внешних ключах модели django можно найти здесь .

0 голосов
/ 09 октября 2019

В этом конкретном случае использования я не могу использовать внешний ключ для создания отношения между обнуляемым столбцом (элементы 'cid') и необнуляемым столбцом (цвета 'id').

Я создалсвязь между данными таблицы 'items' и данными таблицы 'colors' непосредственно внутри модели с использованием метода get_color, который вызывается позже из шаблона:

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>

Во многих случаях установка внешнего ключалучшая практика, как уже упоминалось. Но реализация, показанная выше, полезна, особенно если вы хотите выполнить дополнительное преобразование данных. Обратите внимание, что вы не можете напрямую передавать аргументы методу в вызове шаблона '<td>{{ item.get_color }}</td>'

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...