python - 带条件的嵌套对象列表

标签 python django

我对 django 还很陌生,令我惊讶的是我还没有找到令人满意的答案,但无论如何。

我有以下模型结构(每天点餐):

# Extended user profile
class UserProfile(models.Model)
# One day - daily menu
class OrderingDay(models.Model)
# One menu (there
class MenuItem(models.Model)
    date = models.ForeignKey(OrderingDay, null=True, blank=True)

# One user ordered something during the day
class Order(models.Model):
    user = models.ForeignKey(UserProfile)
    date = models.ForeignKey(OrderingDay)
    item = models.ForeignKey(MenuItem)

有一些菜单每天都会更换(例如鸡汤仅在周一提供,MenuItem.date = not null)和一些餐食(>汉堡包)每天都有供应(MenuItem.date = null)。

我只想列出当前登录用户所做的所有订单:

Monday:
     Hamburger
     Chicken Soup

# Nothing on Tuesday - skip

Wednesday:
    Meatballs 

当用户下订单时,我可以过滤 OrderingDays:

class CurrentOrdersListingView(generic.ListView):
    model = OM.OrderingDay
    context_object_name='ordering_days'

    def get_queryset(self):
        return OM.OrderingDay.filter(order__user=self.request.user)\
               .distinct()

但我无法通过谷歌搜索如何使用重复使用的过滤器列出订单(我发现了 following relations backwards )。

如何实现模板的以下语法:

{% for od in ordering_days %}
<h2>{{ od.date }}</h2>
    {% for item in od.items_by_current_user %}
        {{ item }}
    {% endfor %}
{% endfor %}

最佳答案

Django 可以帮助您创建最常见的查询,而无需诉诸原始 SQL。实际上,弄清楚如何将您想要的内容翻译成 Django 需要您写下的内容可能很棘手。尝试进行查询时要记住的最有用的事情:以您想要的内容开始查询。

如果您想要的是 Orders,您应该查询 Orders(而不是像您在示例中所做的那样查询 OrderingDay 对象)。

那么您想要用户的订单吗?类似于 Order.filter(user=self.request.user)

啊,但是您希望这些订单按天分组吗?最简单的方法是首先通过添加 .values() 来简化查询输出:``Order.filter(user=self.request.user).values('date', 'item') `。这将返回一个简单的字典列表:

[{'date': 'date 1',
  'item': 'hamburgers'},
 {...},
 {...}]  

然后您可以使用'regroup' template tag在你的模板中。根据您的情况,按“日期”重新分组。

或者,您可以用代码来完成。在您的 CurrentOrdersListingView 类中,添加一个 items_per_day() 方法,如下所示:

def items_per_day(self):
    ... your custom grouping code ...
    ... return ['date 1': [item1, item2, item3],
                'date 2': [item2],
                ...

只需在模板中调用该方法即可:

{% for date, items in view.items_per_day %}
  <h2>{{ date }}</h2>
  ....
 {% endfor %}

( View 类上的方法自动在模板中以 view.method_name 形式提供)。

<小时/>

这是最终使用的解决方案:

您可以使用以下方式选择所有订单:

def get_queryset(self):
    return OM.Order.objects.order_by('date__date')\
           .filter(user=self.request.user)

然后使用regroup(它能够完美地处理模型对象)和排序:

{% regroup ordering_days|dictsort:"date.date" by date as ordering_items %}
{% for ordering_day in ordering_items %}
    <h3>{{ ordering_day.grouper.date|date:'l' }}</h3>
    {% for oi in ordering_day.list %}
        {{ oi.item.name }}
    {% endfor %}
{% endfor %}

关于python - 带条件的嵌套对象列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25486963/

相关文章:

python - "sqlite"和 "pysqlite2/sqlite3"模块有什么区别?

python - 类型错误 : unsupported operand type(s) for +: '_sre.SRE_Match' and '_sre.SRE_Match'

python - 如何在 PyQt5 中将 HTML 页面保存为 PDF

python - PIL - TypeError : src is not a numpy array, 既不是标量

python - 具有 orm 关系的最小/最大

python - Django include找不到模板

django - 处理已弃用的 `adminmedia` 模板标签和 {% admin_media_prefix %} 的适当方法

django - Django REST Framework 序列化程序中的嵌套注释字段

python - django-websocket-redis 使用 unix socket 连接 redis

python - 如何使用 Django 获取两条随机记录