V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
yearliny
V2EX  ›  Python

Django 的 models 如何实现 30 天后自动删除?

  •  
  •   yearliny · 2018-01-01 11:57:15 +08:00 via Android · 3166 次点击
    这是一个创建于 2509 天前的主题,其中的信息可能已经有所发展或是发生改变。
    ```半个伪代码
    class Post(models.Model):
    body = TextField()
    POST_STATUS = ((0,'草稿'), (1,'发表'), (2,'回收站'))
    status = CharField(choice=POST_STATUS)
    delete_date = DateField()
    ```
    有一个 Post 的 Model 子类,想要把标记为回收站的文章,删除时间满 30 天后删除。

    我可以想到的实现方式是添加计划任务,每天扫一遍找出删除时间满 30 天的进行删除,但是有哪些更好的的实现方式呢?
    9 条回复    2018-01-02 00:33:53 +08:00
    cljnnn
        1
    cljnnn  
       2018-01-01 12:18:06 +08:00 via Android
    直接 SQL 命令操作 database,可以不?
    leopardwei
        2
    leopardwei  
       2018-01-01 13:01:01 +08:00   ❤️ 1
    crontab、celery 或者自己写个守护进程每天轮询
    Hstar
        3
    Hstar  
       2018-01-01 13:29:48 +08:00   ❤️ 3
    软删除比较简单, 插入时设定过期时间, 查询时过滤过期时间.
    dangyuluo
        4
    dangyuluo  
       2018-01-01 14:21:02 +08:00 via iPhone
    楼上根据时间软删除是正解。
    siteshen
        5
    siteshen  
       2018-01-01 14:32:29 +08:00   ❤️ 1
    class Post(models.Model):
    expires_at = DateField()


    def delete_post(post):
    post.update(expires_at=now() + timedelta(days=30))

    def list_posts():
    Post.query.filter(expires_at < now() + timedelta(days=30)).all()
    incompatible
        6
    incompatible  
       2018-01-01 15:01:41 +08:00   ❤️ 2
    你的通过计划任务定时删除的实现方式就是最好的方式。

    楼上们说的通过时间过滤的方式可行,但是不是最好的方式,在性能敏感的情况下甚至可以说是个很烂的方式。
    明明是一个可以在业务低谷期离线运行的任务,却要加在每一个在线查询里面凭白消耗计算资源。
    RadishWind
        7
    RadishWind  
       2018-01-01 15:06:45 +08:00   ❤️ 1
    1.mysql 有基于时间的 trigger 可以实现这个功能( model.raw("xxxx"))
    2.后台起一个 demon 每天轮询 清除
    3.在 model/middleware/view 中 调用一个检查过期的函数(如果对性能有要求 可以基于概率来做)
    virusdefender
        8
    virusdefender  
       2018-01-01 22:32:13 +08:00
    查询的时候,delete_time__lte=timezone.now - 30days
    yilai
        9
    yilai  
       2018-01-02 00:33:53 +08:00 via Android
    基于时间做软删除,真要在库里删掉的话在写个脚本轮询被
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1633 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 17:03 · PVG 01:03 · LAX 09:03 · JFK 12:03
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.