如何使用Django的信号实现国际化?
- 内容介绍
- 文章标签
- 相关推荐
本文共计1875个文字,预计阅读时间需要8分钟。
目录+ signals + middleware + i18n + settings + django 默认的缓存机制:5+ signals + Django 的 signal 可理解为 Django 内部的钩子,当特定事件发生时,可以触发相应的函数。 + 当一个信号被发出时,Django 会查找所有注册了该信号的接收器,并调用它们。
目录
signals 1
middleware 2
i18n 3
settings 4
django默认的缓存机制: 5
signals
Django的signal可理解为django内部的钩子,当一个事件发生时,其他程序可对其作出相关反应,可通过signal来回调定义好的receivers处理函数,从而更大程度的解耦我们的系统;
使用场景,通知是常用的场景之一(如在论坛中,当帖子得到回复时通知楼主);
Django内置了对数据表|migrate命令|url请求相关|test测试|连接数据库,5大类信号;
Django定义了一系列信号,代码中可监听信号,收到信号后可触发一系列动作;
内置信号:
Model signals:
from django.db.models.signals import
pre_init, post_init # model执行构造方法前后触发
pre_save, post_save保存前(在调用model的save()方法前发送信号)、保存后(在调用model的save()方法后发送信号)
pre_delete, post_delete 删除前(在调用model的delete()方法前发送信号)、删除后(在调用model的delete()方法后发送信号)
m2m_changed #使用多对多字段操作第三张表前后触发
class_prepared # 程序启动时检测已注册的model类,对每个类触发
management signals:
pre_migrate, post_migrate # 执行migrate前后触发
request|response signals:
from django.core.signals import request_started, request_finished请求到来前触发|请求结束后触发
got_request_exception # 请求异常后触发
test signals:
setting_changed # 使用test测试修改配置文件触发
template_rendered # 使用test测试渲染模板时触发
database wrappers:
connection_created # 创建数据库连接时触发
内置信号参数:
django.db.models.signals.pre_save
sender # 模型类
instance # 保存的实际实例(保存后的model数据对象)
raw # 布尔值, True模型完全按提供的方式保存,不应该查询|修改数据库中的其他记录,因为数据库尚未处于一致状态
using # 正在使用的数据库别名
update_fields # 要传递给更新的字段集model.save(),或None如果update_fields未传递给它save()
django.db.models.signals.post_save
sender # 模型类
instance # 保存的实际实例
created # True表示数据创建
raw # 布尔值,True如果模型完全按提供的方式保存,不应该查询|修改数据库中的其它记录,因为数据库尚未处于一致状态
using #
update_fields #
django.db.models.signals.pre_delete
sender #
instance #
using #
django.db.models.signals.post_delete
sender #
instance # 要删除的实际实例,该对象不再存在于数据库中,请谨慎对待此实例
using #
使用方式:
1、手动连接:
from django.db.models.signals import post_delete
def my_callback(sender, **kwargs):
print(sender, '信号已接收')
post_delete.connect(my_callback) # 信号连接接收器,用于收到信号的回调
connect参数:
receiver # 将连接到此信号的回调函数,回调函数名
sender # 指定从中接收信号的特定发送方(如果想要指定某个表对象,直接指定sender)
weak # django默认将信号处理程序存储为弱引用,因此如果您的接收器是本地功能,它可能被垃圾收集,请weak=False在调用信号connect()方法时通过
dispatch_uid # 在可能发送重复信号的情况下信号接收器的唯一标识符
2、receiver装饰器
from django.dispatch import receiver
from django.db.models.signals import post_delete
from app.models import UCenter
@receiver(post_delete, sender=UCenter)
def delete_u2user(sender, instance, **kwargs):
print(sender, instance)
自定义信号使用:
from django.dispatch import Signal
test_signal = Signal(providing_args=['name', 'age']) # 定义信号,声明一个test_signal信号,提供给接收器2个参数
def my_callback(sender, **kwargs):
print(sender, '信号已接收')
test_signal.connect(my_callback) # 注册信号,指定接收器为my_callback
from xxx import test_signal
test_signal.send(sender='test', name='qq', age=18) # 触发信号,Signal.send()不能捕获由接收器提出的任何异常,它只是允许错误传播,因此在面对错误时不是所有接收器都可被通知信号;Signal.send_robust()捕获从python exception类派生的所有错误,并确保所有接收器都收到信号通知,如果发生错误则会在引发错误的接收器的元组对中返回错误实例
例(针对model的signal):
@receiver(post_save, sender=DbManage, dispatch_uid="DbManage_post_save")
def app_create_model_handler(sender, **kwargs):
'''
创建用户的时候创建用户操作日志
kwargs:
{ 'using': 'default', 'update_fields': None, 'instance': < Student: Student object >, 'raw': False,
'created': False, 'signal': < django.db.models.signals.ModelSignal object at0x7f8f48947400 >}
'''
created = kwargs['created']
instance = kwargs['instance']
if created:
# Student_Log.objects.create(action='create', name=instance.name)
# print('create action:%s ' % format(instance.name))
print('!!!create', instance.ip, instance.port)
else:
# Student_Log.objects.create(action='update', name=instance.name)
# print('update action:%s' % format(instance.name))
print('@@@update', instance.ip, instance.port)
@receiver(post_delete, sender=DbManage, dispatch_uid="DbManage_post_delete")
def student_delete_model_handler(sender, **kwargs):
'''
删除用户的时候创建用户操作日志
kwargs:
{'signal': <django.db.models.signals.ModelSignal object at 0x7f5156cf0550>,
'using': 'default', 'instance': <Student: Student object>}
'''
instance = kwargs['instance']
# Student_Log.objects.create(action='delete', name=instance.name)
print('delete action:%s' % format(instance.name))
例:
mysite/books/signals.py
def my_callback(sender, **kwargs):方式1
print('request finished')
request_finished.connect(my_callback)
@receiver(pre_save, sender=Publisher)方式2
def my_handler(sender, **kwargs):
print('do sth action')
mysite/books/apps.py
class BooksConfig(AppConfig):
name = 'books'
def ready(self):
from . import signals
输出:
>>> p = Publisher.objects.create(name='jowin',address='jowin',city='jowin',state_province='jowin',country='cn',website='test')
do sth action
[15/Jan/2019 14:11:27] "GET /favicon.ico HTTP/1.1" 404 2174
request finished
request finished
middleware
中间件是介于request与response处理之间的一道处理过程,用于在全局范围内改变Django的输入和输出。
简单的来说中间件是帮助我们在视图函数执行之前和执行之后都可以做一些额外的操作
例如:
1.Django项目中默认启用了csrf保护,每次请求时通过CSRF中间件检查请求中是否有正确的token值;
2.当用户在页面上发送请求时,通过自定义的认证中间件,判断用户是否已经登陆,未登陆就去登陆;
3.当有用户请求过来时,判断用户是否在白名单或者在黑名单里;
docs.djangoproject.com/en/2.1/topics/127.0.0.1:6379",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
#"CONNECTION_POOL_KWARGS": {"max_connections": 100}
密码",
}
}
},
另添加缓存
"JERD": { }
#3.根据名字去连接池中获取连接
from django_redis import get_redis_connection
conn = get_redis_connection("default")
python manage.py shell
from django.core.cache import cache
cache.set()
cache.has_key()
cache.get()
本文共计1875个文字,预计阅读时间需要8分钟。
目录+ signals + middleware + i18n + settings + django 默认的缓存机制:5+ signals + Django 的 signal 可理解为 Django 内部的钩子,当特定事件发生时,可以触发相应的函数。 + 当一个信号被发出时,Django 会查找所有注册了该信号的接收器,并调用它们。
目录
signals 1
middleware 2
i18n 3
settings 4
django默认的缓存机制: 5
signals
Django的signal可理解为django内部的钩子,当一个事件发生时,其他程序可对其作出相关反应,可通过signal来回调定义好的receivers处理函数,从而更大程度的解耦我们的系统;
使用场景,通知是常用的场景之一(如在论坛中,当帖子得到回复时通知楼主);
Django内置了对数据表|migrate命令|url请求相关|test测试|连接数据库,5大类信号;
Django定义了一系列信号,代码中可监听信号,收到信号后可触发一系列动作;
内置信号:
Model signals:
from django.db.models.signals import
pre_init, post_init # model执行构造方法前后触发
pre_save, post_save保存前(在调用model的save()方法前发送信号)、保存后(在调用model的save()方法后发送信号)
pre_delete, post_delete 删除前(在调用model的delete()方法前发送信号)、删除后(在调用model的delete()方法后发送信号)
m2m_changed #使用多对多字段操作第三张表前后触发
class_prepared # 程序启动时检测已注册的model类,对每个类触发
management signals:
pre_migrate, post_migrate # 执行migrate前后触发
request|response signals:
from django.core.signals import request_started, request_finished请求到来前触发|请求结束后触发
got_request_exception # 请求异常后触发
test signals:
setting_changed # 使用test测试修改配置文件触发
template_rendered # 使用test测试渲染模板时触发
database wrappers:
connection_created # 创建数据库连接时触发
内置信号参数:
django.db.models.signals.pre_save
sender # 模型类
instance # 保存的实际实例(保存后的model数据对象)
raw # 布尔值, True模型完全按提供的方式保存,不应该查询|修改数据库中的其他记录,因为数据库尚未处于一致状态
using # 正在使用的数据库别名
update_fields # 要传递给更新的字段集model.save(),或None如果update_fields未传递给它save()
django.db.models.signals.post_save
sender # 模型类
instance # 保存的实际实例
created # True表示数据创建
raw # 布尔值,True如果模型完全按提供的方式保存,不应该查询|修改数据库中的其它记录,因为数据库尚未处于一致状态
using #
update_fields #
django.db.models.signals.pre_delete
sender #
instance #
using #
django.db.models.signals.post_delete
sender #
instance # 要删除的实际实例,该对象不再存在于数据库中,请谨慎对待此实例
using #
使用方式:
1、手动连接:
from django.db.models.signals import post_delete
def my_callback(sender, **kwargs):
print(sender, '信号已接收')
post_delete.connect(my_callback) # 信号连接接收器,用于收到信号的回调
connect参数:
receiver # 将连接到此信号的回调函数,回调函数名
sender # 指定从中接收信号的特定发送方(如果想要指定某个表对象,直接指定sender)
weak # django默认将信号处理程序存储为弱引用,因此如果您的接收器是本地功能,它可能被垃圾收集,请weak=False在调用信号connect()方法时通过
dispatch_uid # 在可能发送重复信号的情况下信号接收器的唯一标识符
2、receiver装饰器
from django.dispatch import receiver
from django.db.models.signals import post_delete
from app.models import UCenter
@receiver(post_delete, sender=UCenter)
def delete_u2user(sender, instance, **kwargs):
print(sender, instance)
自定义信号使用:
from django.dispatch import Signal
test_signal = Signal(providing_args=['name', 'age']) # 定义信号,声明一个test_signal信号,提供给接收器2个参数
def my_callback(sender, **kwargs):
print(sender, '信号已接收')
test_signal.connect(my_callback) # 注册信号,指定接收器为my_callback
from xxx import test_signal
test_signal.send(sender='test', name='qq', age=18) # 触发信号,Signal.send()不能捕获由接收器提出的任何异常,它只是允许错误传播,因此在面对错误时不是所有接收器都可被通知信号;Signal.send_robust()捕获从python exception类派生的所有错误,并确保所有接收器都收到信号通知,如果发生错误则会在引发错误的接收器的元组对中返回错误实例
例(针对model的signal):
@receiver(post_save, sender=DbManage, dispatch_uid="DbManage_post_save")
def app_create_model_handler(sender, **kwargs):
'''
创建用户的时候创建用户操作日志
kwargs:
{ 'using': 'default', 'update_fields': None, 'instance': < Student: Student object >, 'raw': False,
'created': False, 'signal': < django.db.models.signals.ModelSignal object at0x7f8f48947400 >}
'''
created = kwargs['created']
instance = kwargs['instance']
if created:
# Student_Log.objects.create(action='create', name=instance.name)
# print('create action:%s ' % format(instance.name))
print('!!!create', instance.ip, instance.port)
else:
# Student_Log.objects.create(action='update', name=instance.name)
# print('update action:%s' % format(instance.name))
print('@@@update', instance.ip, instance.port)
@receiver(post_delete, sender=DbManage, dispatch_uid="DbManage_post_delete")
def student_delete_model_handler(sender, **kwargs):
'''
删除用户的时候创建用户操作日志
kwargs:
{'signal': <django.db.models.signals.ModelSignal object at 0x7f5156cf0550>,
'using': 'default', 'instance': <Student: Student object>}
'''
instance = kwargs['instance']
# Student_Log.objects.create(action='delete', name=instance.name)
print('delete action:%s' % format(instance.name))
例:
mysite/books/signals.py
def my_callback(sender, **kwargs):方式1
print('request finished')
request_finished.connect(my_callback)
@receiver(pre_save, sender=Publisher)方式2
def my_handler(sender, **kwargs):
print('do sth action')
mysite/books/apps.py
class BooksConfig(AppConfig):
name = 'books'
def ready(self):
from . import signals
输出:
>>> p = Publisher.objects.create(name='jowin',address='jowin',city='jowin',state_province='jowin',country='cn',website='test')
do sth action
[15/Jan/2019 14:11:27] "GET /favicon.ico HTTP/1.1" 404 2174
request finished
request finished
middleware
中间件是介于request与response处理之间的一道处理过程,用于在全局范围内改变Django的输入和输出。
简单的来说中间件是帮助我们在视图函数执行之前和执行之后都可以做一些额外的操作
例如:
1.Django项目中默认启用了csrf保护,每次请求时通过CSRF中间件检查请求中是否有正确的token值;
2.当用户在页面上发送请求时,通过自定义的认证中间件,判断用户是否已经登陆,未登陆就去登陆;
3.当有用户请求过来时,判断用户是否在白名单或者在黑名单里;
docs.djangoproject.com/en/2.1/topics/127.0.0.1:6379",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
#"CONNECTION_POOL_KWARGS": {"max_connections": 100}
密码",
}
}
},
另添加缓存
"JERD": { }
#3.根据名字去连接池中获取连接
from django_redis import get_redis_connection
conn = get_redis_connection("default")
python manage.py shell
from django.core.cache import cache
cache.set()
cache.has_key()
cache.get()

