zoukankan      html  css  js  c++  java
  • Django 1.6 最佳实践: 如何正确使用 Signal(转)

    原文:http://www.weiguda.com/blog/38/

    如何正确的使用signal:

    简单回答是: 在其他方法无法使用的情况下, 才最后考虑使用signal.

    因为新的django开发人员得知signal之后, 往往会很高兴去使用它. 他们在能使用signal的地方就使用signal, 并且这是他们觉得自己是django专家一样. 然而,

    像这样编码一段时间后, django项目就会变得异常复杂, 许多内容都纠结在一起无法解开.

    许多开发者也会将django signal和异步消息列队(例如celery)搞混. signal是同步处理, 因此通过signal调用大处理量的进程时并无法提高性能. 事实上, 将这些

    需要大处理量的进程移到signal中被视作是一种不好的习惯.

    1. 何时使用signal

    以下情况不要使用signal:

    • signal与一个model紧密相关, 并能移到该model的save()时
    • signal能使用model manager代替时
    • signal与一个view紧密相关, 并能移到该view中时

    以下情况可以使用signal:

    • signal的receiver需要同时修改对多个model时
    • 将多个app的相同signal引到同一receiver中处理时
    • 在某一model保存之后将cache清除时
    • 无法使用其他方法, 但需要一个被调函数来处理某些问题时

    2. Signal的代替方法

    使用mod而来manager

    以下代码演示了当用户创建Event model时, 需要通知管理员, 如果改写model中的post_save(), 则需要添加额外的逻辑来区分用户还是管理员:

        # myapp/managers.py
        from django.db import models
    
        class EventManager(models.Manager):
    
            def create_event(self, title, start, end, creator):
                event = self.model(title=title, start=start, end=end, creator=creator)
                event.save()
                event.notify_admins()
                return event

    在model中设置model manager:

        # myapp/models.py
        from django.conf import settings
        from django.core.mail import mail_admins
        from django.db import models
    
        from model_utils.models import TimeStampedModel
        from .managers import EventManager
    
        class Event(TimeStampedModel):
    
            STATUS_UNREVIEWED, STATUS_REVIEWED = (0, 1)
            STATUS_CHOICES = (
                (STATUS_UNREVIEWED, "Unreviewed"),
                (STATUS_REVIEWED, "Reviewed")
            )
    
            title = models.CharField(max_length=100)
            start = models.DateTimeField()
            end = model.dateTimeField()
            status = models.IntegerField(choices=STATUS_CHOICES, default=STATUS_UNREVIEWED)
            creator = models.ForeignField(settings.AUTH_USER_MODEL)
            objects = EventManager()
    
            def notify_admins(self):
                subject = "{user} submitted a new event!".format(user=self.creator.get_full_name())
                message = """TITLE: {title}
                    START: {start}
                    END: {end}""".format(title=self.title, start=self.start, end=self.end)
                mail_admins(subject=subject, message=message, fail_silently=False)

    在view中使用create_event()代替create()时, 便会通知管理员了.

    在其他代码中验证model

    如果你使用pre_save signal来验证某一model, 则应当尝试自己写一个validator取代之. 如果验证是通过ModelForm时, 通过改写clean()实现验证.

    使用model的save()和delete()

    如果使用pre_save 或 post_save signal, 如果可以, 则将这些代码移到model的save()方法中.

    同样如果使用pre_delete 或 post_delete signal, 如果可以, 则将这些代码移到model的delte()方法中.

    使用其他代码代替signal

    如果可能, 我们可以将signal的逻辑使用其他帮助程序实现.

  • 相关阅读:
    zTree根据json选中节点,并且设置其他节点不可选
    点击一次按钮,发生多次ajax请求
    sublimeText3 中配置sass环境,并将编译后文件保存到指定文件夹
    MD5加密
    c# Http请求之HttpClient
    xml与object 之间的ORM
    wpf和winform的那点区别
    c# http请求ajax页面
    c# https请求
    python爬虫框架Pyspider初次接触
  • 原文地址:https://www.cnblogs.com/ajianbeyourself/p/4181410.html
Copyright © 2011-2022 走看看