Django ORM。如何排除旧数据?

Posted

技术标签:

【中文标题】Django ORM。如何排除旧数据?【英文标题】:Django ORM. How to exclude old data? 【发布时间】:2019-12-14 11:16:41 【问题描述】:

我想从我的查询集中排除不重要的旧记录。

我尝试使用 annotate(Max('pc_users__created')),但这不是我想要的。我想我应该使用“分组依据”或类似的东西,但我不明白如何。

这是我的models.py

class Room(models.Model):
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)
    room_number = models.SmallIntegerField()

    def __str__(self):
        return f'Room №self.room_number'


class UserProfiles(models.Model):
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)
    name = models.CharField(max_length=100)

    def __str__(self):
        return f'self.name'


class Pc(models.Model):
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)
    title = models.CharField(max_length=100)
    ram = models.SmallIntegerField()
    cpu = models.CharField(max_length=20)
    gpu = models.CharField(max_length=20)

    def __str__(self):
        return f'self.title'


class PcUsers(models.Model):
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)
    pc = models.ForeignKey(Pc, on_delete=models.PROTECT, related_name='pc_users')
    user = models.ForeignKey(UserProfiles, on_delete=models.PROTECT)

    def __str__(self):
        return f'self.pc: self.user'


class PcRooms(models.Model):
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)
    pc = models.ForeignKey(Pc, on_delete=models.PROTECT, related_name='pc_rooms')
    room = models.ForeignKey(Room, on_delete=models.PROTECT)

    def __str__(self):
        return f'self.pc: self.room'

和views.py: from myapp.models 导入电脑

def report(request):
    data = Pc.objects.values(
        'id',
        'title',
        'pc_users__user__name',
        'pc_rooms__room__room_number'
    )
    return render(request, 'report.html', 'data': data)

这也是我来自管理站点的data

我想排除所有重复记录并保留所有最新记录。 Like this

+-------+------------+---------+---------+
| ID Pc |  Pc Title  | Pc User | Pc Room |
+-------+------------+---------+---------+
|     1 | Laptop     | User1   |     201 |--> Keep this
|     1 | Laptop     | User1   |     999 |
|     1 | Laptop     | Admin   |     201 |
|     1 | Laptop     | Admin   |     999 |
|     2 | PC1        | User1   |     201 |--> Keep this
|     2 | PC1        | User1   |     202 |
|     2 | PC1        | User2   |     201 |
|     2 | PC1        | User2   |     202 |
|     3 | PC2        | User2   |     202 |--> Keep this
|     3 | PC2        | User2   |     203 |
|     3 | PC2        | User3   |     202 |
|     3 | PC2        | User3   |     203 |
|     4 | PC3        | User3   |     203 |--> Keep this
|     4 | PC3        | User3   |     201 |
|     4 | PC3        | User1   |     203 |
|     4 | PC3        | User1   |     201 |
|     5 | Server     | Admin   |     999 |--> Keep this
|     6 | new laptop | None    |     301 |--> Keep this
+-------+------------+---------+---------+

【问题讨论】:

【参考方案1】:

使用distinct() 排除重复,使用order_by 使用created 字段保留最新记录

【讨论】:

我试过了,但是 distinct 只能在一个模型上工作,一个查询集中有 3 个模型(Pc、PcUsers 和 PcRooms)或者我应该使用 distinct('pc_id_field')? 可以,国外领域可以用distinct,看看docs.djangoproject.com/en/2.2/ref/models/querysets/… 非常感谢!!我应该注意 ordering、order_by 和 distinct 方法,应该包括相同的字段,例如: order_by('id', 'pc_users__created').distinct('id')

以上是关于Django ORM。如何排除旧数据?的主要内容,如果未能解决你的问题,请参考以下文章

将遗留的 mySQL 数据库集成到新的 Django ORM 驱动的数据结构中

如果找到湮灭对,Django ORM 排除结果

python脚本中使用django orm

需要从 spring boot 2.0 中排除 spring-orm 模块并从 jar 文件中使用它的旧版本

带有排除的 Django ORM 查询无法正常工作

django ORM - 在 M2M 上排除 F 功能不起作用