6

我的模型文件中有一个表,我想将其设计为表中的行数限制为十行。当超过限制时,最旧的行将被删除。在某些情况下,这是在前端显示,向用户显示他们最近访问过的十个链接。我是 Django 的新手,所以如果有人对如何做到这一点有任何建议,将不胜感激!

4

3 回答 3

6

您可以编写一个自定义save方法来检查 的长度YourObject.objects.all(),然后在该长度等于 10 时删除最旧的。

类似的东西:

def save(self, *args, **kwargs):
    if YourModel.objects.count() == 10:
        objects[0].delete()

    super(YourModel, self).save(*args, **kwargs)
于 2013-08-08T20:37:30.323 回答
4

在我看来,您可以使用Signals。A post_save在这种情况下。这样,您可以将对象创建和删除逻辑分开。

由于您希望oldest删除 ,我假设您created在模型中有一个字段。

一旦你save

def my_handler(sender, instance, **kwargs):
    qs = MyModel.objects.order_by('created') #ensure ordering.
    if qs.count() > 10:
        qs[0].delete() #remove the oldest element

class MyModel(models.Model):
    title = models.CharField('title', max_length=200)
    created = models.DateTimeField(auto_add_now=True, editable=False)

post_save.connect(my_handler, sender=MyModel)

当然,没有什么能阻止您使用pre_save信号,但只有在您绝对确定该save方法不会失败时才使用它。

于 2013-08-08T20:47:22.953 回答
0

对@karthikr 的回答有所改进。

我也相信保存后信号处理程序是最好的方法,但在类方法中隔离函数并检查created标志。例如,如果您想保留系统发送的最后 1000 封电子邮件的日志:

from django.db import models
from django.db.models.signals import post_save

LOG_SIZE=1000

class EmailLog(models.Model):
    """Keeps a log of the 1000 most recent sent emails."""

    sent_at = models.DateTimeField(auto_add_now=True)
    message = models.TextField()
    to_addr = models.EmailField()

    @classmethod
    def post_create(
        cls,
        sender,
        instance: "EmailLog",
        created: bool,
        *args,
        **kwargs
    ):
        if created: # Indicates if it's a new object
            qset = EmailLog.objects.order_by("sent_at") # Force ordering
            if qset.count() > LOG_SIZE:
                qset[0].delete()


post_save.connect(EmailLog.post_create, sender=EmailLog)
于 2022-01-28T15:05:01.120 回答