首页 > 解决方案 > 如何对包含用户作为显示每个用户数据的页面的外键的模型进行排序?

问题描述

我想让我的主页成为显示每个用户信息的主页。

on Models.py (simplified, not actual code):
class User(models.Model):
    name = models.CharField()
    level = models.IntegerField()

class History(models.Model):
    name = models.ForeignKey('User', on_delete = models.CASCADE)
    history = models.CharField()

on HTML:
{% for user in users %}
    <p>{{ user.name }}</p>
    {% for history in histories.objects.filter(name__exact=User.id) %}
        <p> {{ history }} </p>//sorted history that contains 'user' as ForeignKey
    {% endfor %}
    <p>{{ user.level }}</p>
{% endfor %}

使用上述方法在用户模型中显示信息成功,但我无法为“用户”排序历史模型。我如何展示这个模型,从“用户”获取密钥并对其进行排序?

我现在正在使用最新版本的 Django 2.1,并且我已经尝试从“用户”获取 pk 值,并将其发送到 views.py,但这没有帮助。

Expected: 
<p>User 01</p> //Name
<p>Changed name user01 to User 01</p>
<p>Level increased to 25</p>
<p>Level increased to 26</p>  //History
<p>LV 26</p> //Level

<p>User 02</p> //Name
<p>Level increased to 32</p>
<p>Changed name user02 to User 02</p>
<p>Level increased to 33</p>  //History
<p>LV 33</p> //Level

Actual:
<p>User 01</p>
<p></p>
<p>Lv 26</p>

<p>User 02</p>
<p></p>
<p>Lv 33</p>

标签: htmldjangopython-3.xdjango-models

解决方案


有几种方法可以做到这一点。一种方法是扩展 Manager 实例并添加自定义方法,该方法返回按 id 排序的记录。像这样:

class HistoryManager(models.Manager):
    def latest_records(self):
        return super().get_queryset().order_by('-id')

class History(models.Model):
    name = models.ForeignKey('User', on_delete = models.CASCADE, related_name='histories')
    history = models.CharField()
    objects = HistoryManager()

{% for user in users %}
    <p>{{ user.name }}</p>
    {% for history in user.histories.latest_records %}
        <p> {{ history }} </p>//sorted history that contains 'user' as ForeignKey
    {% endfor %}
    <p>{{ user.level }}</p>
{% endfor %}

另一种方法是在 User 模型的实例中创建一个方法

class History(models.Model):
    name = models.ForeignKey('User', on_delete = models.CASCADE, related_name='histories')
    history = models.CharField()

class User(models.Model):
    name = models.CharField()
    level = models.IntegerField()
    def latest_history():
        return self.histories.order_by('-id')

{% for user in users %}
    <p>{{ user.name }}</p>
    {% for history in user.latest_history %}
        <p> {{ history }} </p>//sorted history that contains 'user' as ForeignKey
    {% endfor %}
    <p>{{ user.level }}</p>
{% endfor %}

推荐阅读