我想将模型的记录限制 for each 用户最多10行(模型具有用户模型的外部键).最佳做法是什么?

我考虑过重写保存方法,执行判断,并在保存之前删除:

def save(self, *args, **kwargs):
 if MyModel.objects.filter(user=self.user).count() >= 10:
     oldest_record =         MyModel.objects.filter(user=self.user).order_by('created_at').first()
 oldest_record.delete()
 super().save(*args, **kwargs)

但我想知道这是否是一个好的解决方案,在数据库级别执行是否更好(以及如何实现它),以及当同一用户同时保存两个实例时潜在的问题(尽管不太可能).有类似的经历吗?

推荐答案

您可以通过使用user_id而不是user来提高效率,因为它阻止获取用户.

我们还可以在一次获取中获得所有项目,从而防止某些竞争条件:

def save(self, *args, **kwargs):
    if instance._state.adding:
        items = (
            MyModel.objects.filter(user_id=self.user_id)
            .order_by('created_at')
            .only('pk')[9:]
        )
        if items:
            MyModel.objects.filter(pk__in={item.pk for item in items}).delete()
    super().save(*args, **kwargs)

但是重写.save()个方法、信号等都可以被批量操作(如批量创建)绕过.

如果在数据库级别上执行这一点更好(以及如何做到这一点).

can使用UniqueConstraint在数据库级别执行此操作,这使得user_id和主键的组合模10是唯一的.在这种情况下,逻辑转移到 Select 一个好的主键.

这意味着对于用户,我们可以分配例如具有主键512632等的项目,但不是31,因为…1已经被"选中"了.

可能最好是定期运行管理命令来清理旧记录,并且在前端始终将用户的MyModel数量限制为10.这可能是相当强大的.

Django相关问答推荐

未显示SWAGER上的一些示例架构

如何从Django';S模型中的方法中检索值?

没有与给定查询匹配的监视列表

django-filter compose 过滤的 url

通过 B 的外键列表访问模型 B 的行

按下按钮刷新在html文件中显示的变量

为什么我的搜索功能返回错误相关字段查找无效:​​类别

如何将 ManyToManyField 与另一个 ManyToManyField 进行比较

带有代码完成功能的 python / django 的 Sublime Text 2 和 3 设置

使用 args 和选项编写自定义管理命令 - 所需字段说明

如何解决 AssertionError: .accepted_renderer not set on Response in django and ajax

多租户 Django 应用程序:根据请求更改数据库连接?

Django Facebook Connect 应用推荐

将网络测功机添加到 Heroku django 应用程序时如何克服Coudn't find that formation错误?

ImportError:无法导入设置

URL命名空间的一个真实例子

在python中查找对对象的所有引用

Django:在管理界面中显示图像

只使用 Django 的某些部分?

确保只有一个工作人员在运行多个工作人员的 pyramid 网络应用程序中启动 apscheduler 事件