【问题标题】:Limit the number of rows in a Django table限制 Django 表中的行数
【发布时间】:2023-03-29 20:11:01
【问题描述】:

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

【问题讨论】:

    标签: django django-models


    【解决方案1】:

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

    类似的东西:

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

    【讨论】:

    • 更好用objects.count()
    • P.S.这在您的模型定义中覆盖默认保存方法。
    【解决方案2】:

    在我看来,你可以使用Signals。在这种情况下为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 方法不会失败的情况下才使用它。

    【讨论】:

    • 如果同时保存两个实例会怎样?
    【解决方案3】:

    对@karthikr 的回答有所改进。

    我也相信post-save 信号处理程序是最好的方法,但在类方法中隔离函数并检查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)
    

    【讨论】:

      猜你喜欢
      • 2015-12-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多