Django - получить все связанные модели, связанные с каждым объектом

Ochmar спросил: 28 апреля 2018 в 08:34 в: crystal-reports

В принципе, у меня есть несколько моделей, которые ссылаются друг на друга. Надеюсь, что у меня есть отношения между ними, но я не уверен на 100%. models.py

class Table(models.Model):
    number = models.IntegerField(unique = True)
    isFree = models.BooleanField(default = True)class MenuItem(models.Model):
    name = models.CharField(max_length = 200)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    quantityInStock = models.PositiveSmallIntegerField(default=10)class Order(models.Model):
    tableFK = models.ForeignKey(Table, on_delete=models.CASCADE)
    opened_at = models.DateTimeField('date_created', default = timezone.now)
    closed_at = models.DateTimeField('date_closed', blank = True, null = True)
    paid = models.BooleanField(default = False)
    class Meta:
         ordering = ('-opened_at',)class OrderDetails(models.Model):
    STATUS_CHOICES = (
        ('CHOICE1', 'choice1'),
        ('CHOICE2', 'choice2'),
        ('CHOICE3', 'choice3'),
        ('CHOICE4', 'choice4'),
        ('CHOICE5', 'choice5')
    )    orderFK = models.ForeignKey(Order, on_delete = models.CASCADE)
    menuitemFK = models.ForeignKey(MenuItem, on_delete = models.CASCADE)
    quantity = models.PositiveSmallIntegerField(default = 1)
    status = models.CharField(max_length=5, choices= STATUS_CHOICES, default='choice1')

views.py

def index(request):
    orders = Order.objects.select_related("tableFK").filter(paid=False)    template = loader.get_template('autowaiter/index.html')
    context = {
        'orders':orders
    }
    return HttpResponse(template.render(context))

Теперь я добиваюсь того, что у меня есть объекты Orders. Но в index.html я хотел бы отобразить что-то вроде:

  • Таблица
  • "самый ранний" порядок в таблице
  • ВСЕ элементы OrderDetails, сгруппированные по каждому orderFK

Не могли бы вы указать мне пример и теорию, которых мне не хватает?

2 ответа

Есть решение
Will Keeling ответил: 28 апреля 2018 в 11:09

Предполагая, что я понял, что вы ищете, очень простой шаблон, основанный на вашей текущей структуре модели, может выглядеть примерно так:

{% for table in tables %}
    <h3>Table {{ table.number }}</h3>
    <p>Order opened at {{ table.orders.earliest.opened_at }}</p>
    {% for orderdetail in table.orders.earliest.orderdetails.all %}
        Status: {{ orderdetail.status }}, Quantity: {{ orderdetail.quantity }}
        </br>
    {% endfor %}
    <hr/>
{% endfor %}

Но вам нужно будет внесите некоторые изменения в ваши модели, чтобы поддержать это, а именно добавление атрибута related_name в поле вашего внешнего ключа в Order:

tableFK = models.ForeignKey(Table, related_name='orders', on_delete=models.CASCADE)

и в OrderDetail:

orderFK = models.ForeignKey(Order, related_name='orderdetails', on_delete = models.CASCADE)

, а также добавить атрибут get_latest_by в класс Meta в Order:

class Meta:
    ordering = ('-opened_at',)
    get_latest_by = 'opened_at'

(который поддерживает использование earliest).

Наконец, запрос в вашем представлении понадобится для запроса объектов верхнего уровня Table, которые имеют неоплаченные заказы, а не для самих запросов:

def index(request):
    # Query the tables with unpaid orders
    tables = Table.objects.filter(orders__paid=False)    template = loader.get_template('autowaiter/index.html')
    context = {
        'tables': tables
    }
    return HttpResponse(template.render(context))
Ochmar ответил: 28 апреля 2018 в 11:26
Я думаю, что это то, что мне было нужно, с таблицами = Table.objects.filter (orders__paid = False) больше всего. Я не мог найти синтаксис, который бы соответствовал моим потребностям. Большое спасибо!
Vinay P ответил: 28 апреля 2018 в 09:03

Если вы этого не сделали, попробуйте django_tables2, HTML-таблицы могут быть сгенерированы и отображены с гиперссылкой столбцов по внешним ключам на новую страницу или таблицу.

Ochmar ответил: 28 апреля 2018 в 09:21
Это определенно то, что я попробую! Большое спасибо!