2-Django使用示例
官方文档
websocket支持
过程笔记
static 目录找不到资源 异步支持 django values_list exec 无效 使用{% url } iframe 不允许渲染 集成LDAP
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
urlpatterns = [
path('admin/', admin.site.urls),
re_path('', include('usermodectl.urls'))
]
urlpatterns += staticfiles_urlpatterns()
或者
from django.conf import settings
from django.contrib import admin
from django.urls import path , re_path , include
from django.views.static import serve
from usermodectl.views import *
urlpatterns = [
path ( 'admin/' , admin . site . urls ),
re_path ( r "^static/(?P<path>.*)$" , serve , { "document_root" : settings . STATIC_ROOT }, name = 'static' ),
re_path ( '' , include ( 'usermodectl.urls' ))
]
STATIC_ROOT = os . path . join ( BASE_DIR , "static" )
用Uvicorn来启动ASGI组件
pip install uvicorn
启动:
uvicorn djangoProject.asgi:application
协程
# 异步视图
async def index(request):
return HttpResponse("Hello, Django!")
async def async_view(request):
loop = asyncio.get_event_loop()
loop.create_task(async_task())
return HttpResponse("Hello, async Django!")
bug_sum.objects.values_list(“teamname”,flat=True).distinct() # :
bug_sum.objects.values_list(“teamname”).distinct() # :
定义在了命名空间字典 namespace 中。然后,使用 exec() 执行代码,并通过命名空间字典获取执行后的结果。
namespace = {}
exec(svnaddr, namespace)
logging.error(namespace.get("components_list_rootfs"))
logging.error(namespace.get("components_list"))
由于x-frame-options设置了deny属性,导致了iframe失效,x-frame-options响应头是用来给浏览器设置允许一个页面可否在<frame>、<iframe>中展现的标记,有三个属性
deny:页面不允许在iframe中展现,相同域名嵌套也不允许
sameorigin:允许在相同域名嵌套展示
allow-from uri:允许指定源的iframe展示,即白名单
特性配置
静态、模板配置 app中的 url 路由写法 模板-字典 修改登录页 中间件说明
静态配置目录
settings.py 文件中添加
STATIC_ROOT = os.path.join(BASE_DIR,"static")
urls.py 文件中添加
re_path(r"^static/(?P<path>.*)$", serve, {"document_root": settings.STATIC_ROOT}, name='static'),
模板配置
settings.py 文件 变量 TEMPLATES 修改dirs
'DIRS': [BASE_DIR / 'templates', ],# 即模板文件存放在 BASE_DIR/templates
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Shanghai'
USE_I18N = True
USE_L10N = True
USE_TZ = False
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.2/howto/static-files/
STATIC_URL = '/static/'
STATICFILES_DIRS = [
BASE_DIR / 'static',
]
from django.urls import re_path
from aboutpbc.views import *
app_name = 'aboutpbc'
urlpatterns = [
re_path("",index,name="index")
]
urlpatterns = [
re_path('^$', index_page),# 一般首页的写法
re_path('model_info', model_info),
# 正则匹配 其中 name可以在模板网页中使用 <a href="{% url "queryproduct" per_model.1 %}"
re_path("query/(?P<product_name>.*)", product_list,name="queryproduct"),
path('contol/', admin.site.urls),# 修改默认的管理地址
re_path("",include("cneos.urls")),# 走到某个app
]
{% for key,value in dicts.items %}
<tr class="{% cycle 'altrow' '' %}">
<td>{{ forloop.counter }}</td>
<td>{{ key }}</td>
<td>{{ value }}</td>
</tr>
{% endfor %}
下面两种也是,循环k - v
{% for row in user_dict.keys %}
{% for row in user_dict.values %}
要修改 Django 后台管理左上角的 “Django 管理” 为 “公共服务”,你需要覆盖 Django 的默认 admin 模板。下面是具体步骤:
在你的 Django 项目的主目录下(与 manage.py 文件在同一级别),创建一个名为 templates 的文件夹。
在 templates 文件夹下,创建一个名为 admin 的文件夹。这是为了覆盖 Django admin 的默认模板。
在 admin 文件夹下,创建一个名为 base_site.html 的文件。Django admin 会首先搜索这个文件,如果找到,就会使用它替代默认的模板。
在 base_site.html 文件中,你需要继承 admin/base.html,并覆盖 branding 块,如下所示:
{% extends "admin/base.html" %}
{% load i18n %}
{% block title %}{{ title }} | {% trans "公共服务" %}{% endblock %}
{% block branding %}
< h1 id = "site-name" >< a href = "{% url 'admin:index' %}" > {% trans "公共服务" %}</ a ></ h1 >
{% endblock %}
{% block nav-global %}{% endblock %}
确保你的 Django 项目知道这个新的 templates 文件夹的位置。在你的 settings.py 文件中,你应该有一个名为 TEMPLATES 的设置。在这个设置中,你需要添加你刚刚创建的 templates 文件夹的路径,如下所示:
TEMPLATES = [
{
...
'DIRS' : [ os . path . join ( BASE_DIR , 'templates' )],
...
},
]
这样,当你再次打开 Django admin 页面时,你应该会看到左上角的 “Django 管理” 已经被改为 “公共服务”。
1、具体的app里面 新建middle 文件夹
2、创建中间件代码,具体参考下方代码
3、在setting的MIDDLERWARE 中注册中间件
from django.utils.deprecation import MiddlewareMixin
class letdo ( MiddlewareMixin ):
# 它应该返回 None 或 HttpResponse 对象。如果它返回 None ,Django 将继续处理这个请求
''' 顺序
调用 self.process_request(request) (如果被定义过)。
调用 self.get_response(request) 来从后续的中间件和视图得到响应。
调用 self.process_response(request, response) (如果被定义过)。
返回响应。
'''
def __call__ ( self , request ):
'''
:param request:是中间件的主要入口点。当请求到达时,Django将调用中间件的__call__方法,传递request对象作为参数。
中间件可以在这个方法中执行任何预处理或处理请求的操作,例如记录请求信息、检查用户身份、设置一些请求标志等。
:return:
'''
...
def process_view ( self , request , view_func , view_args , view_kwargs ):
''' 只在 Django 调用视图前被调用;这个方法在请求被路由到视图函数之前被调用
request 是一个 HttpRequest 对象。
view_func 是一个 Django 将要使用的 Python 函数。(这是一个真实的函数对象,不是函数的名称);
view_args 是一个用来传递给视图的位置参数列表,;
view_kwargs 是一个用来传递给视图的关键字参数字典。
view_args 和 view_kwargs 都不包含第一个视图参数 ( request )。
'''
...
def process_exception ( self , request , exception ):
'''
当视图引发异常时,Django 会调用
:param request:
:param exception:
:return:
'''
...
def process_template_response ( self , request , response ):
'''
在视图被完全执行后调用;它必须返回一个实现了 render 方法的响应对象
当视图函数返回一个模板响应时,这个方法会被调用。中间件可以在这里对模板响应进行处理,例如添加额外的上下文变量或修改响应内容。
:param request:
:param response:
:return:
'''
...
def process_request ( self , request ):
'''
这个方法在__call__方法之前调用。它允许中间件在请求处理之前进行一些操作
'''
...
def process_response ( self , request , response ):
# 这个方法在视图函数处理请求并生成响应后调用
...
数据相关
查询器语法 自定义过滤器 常见内置过滤器 数据迁移
语法
效果
~Q(jira_key__istartswith=”ARC”)
不以ARC开头的任务
__exact
精确等于 like ‘111’
__iexact
精确等于 忽略大小写 ilike ‘111’
__contains
包含 like ‘%111%’
__icontains
包含 忽略大小写 ilike ‘%111%’,
__gt
大于
__gte
大于等于
__lt
小于
__lte
小于等于
__in
存在于一个list范围内
__startswith
以…开头
__istartswith
以…开头 忽略大小写
__endswith
以…结尾
__iendswith
以…结尾,忽略大小写
__range
在…范围内
__year
日期字段的年份
__month
日期字段的月份
__day
日期字段的日
__isnull=True/False
Django自定义过滤器
第一步: 在app目录下创建包 templatetags
在templatetags下创建py文件,文件名随意
自定义过滤器函数filter
from django.template import Library
import datetime
register = Library ()
def show_time ( v ):
# 首页返回底部时间的过滤器
return datetime . datetime . now () . date ()
register . filter ( 'show_time' , show_time )
第二步,html引用
在文件开头导入
{% load my_page %}
使用
重启服务器!!!!!!
Django过滤器
过滤器
描述
upper
以大写方式输出
{{ user.name | upper }}
add
给value加上一个数值
{{ user.age | add:”5” }}
addslashes
单引号加上转义号
capfirst
第一个字母大写
{{ ‘good’| capfirst }} 返回”Good”
center
输出指定长度的字符串,把变量居中
{{ “abcd”| center:”50” }}
cut
删除指定字符串
{{ “You are not a Englishman” | cut:”not” }}
date
格式化日期
{{ 时间|date:”Y-m-d” }}
default
如果值不存在,则使用默认值代替
{{ value | default:”(N/A)” }}
default_if_none
如果值为None, 则使用默认值代替
dictsort
按某字段排序,变量必须是一个dictionary
{% for moment in moments | dictsort:”id” %}
dictsortreversed
按某字段倒序排序,变量必须是dictionary
divisibleby
判断是否可以被数字整除
{{ 224 | divisibleby:2 }} 返回 True
escape
按HTML转义,比如将”;”转换为”<”
filesizeformat
增加数字的可读性,转换结果为13KB,89MB,3Bytes等
{{ 1024 | filesizeformat }} 返回 1.0KB
first
返回列表的第1个元素,变量必须是一个列表
floatformat
转换为指定精度的小数,默认保留1位小数
{{ 3.1415926 | floatformat:3 }} 返回 3.142 四舍五入
get_digit
从个位数开始截取指定位置的数字
{{ 123456 | get_digit:’1’}}
join
用指定分隔符连接列表
{{ [‘abc’,’45’] | join:’*’ }} 返回 abc*45
length
返回列表中元素的个数或字符串长度
length_is
检查列表,字符串长度是否符合指定的值
{{ ‘hello’| length_is:’3’ }}
linebreaks
用;p;或;br;标签包裹变量
{{ “Hi\n\nDavid”|linebreaks }} 返回;p;Hi;/p;;p;David;/p;
linebreaksbr
用;br/;标签代替换行符
linenumbers
为变量中的每一行加上行号
ljust
输出指定长度的字符串,变量左对齐
{{‘ab’|ljust:5}}返回 ‘ab ’
lower
字符串变小写
make_list
将字符串转换为列表
pluralize
根据数字确定是否输出英文复数符号
random
返回列表的随机一项
removetags
删除字符串中指定的HTML标记
{{value | removetags: “h1 h2”}}
rjust
输出指定长度的字符串,变量右对齐
slice
切片操作, 返回列表
{{[3,9,1] | slice:’:2’}} 返回 [3,9]{{ ‘asdikfjhihgie’ | slice:’:5’ }} 返回 ‘asdik’
slugify
在字符串中留下减号和下划线,其它符号删除,空格用减号替换
{{ ‘5-2=3and5 2=3’ | slugify }} 返回 5-23and5-23
stringformat
字符串格式化,语法同python
time
返回日期的时间部分
timesince
以“到现在为止过了多长时间”显示时间变量
结果可能为 45days, 3 hours
timeuntil
以“从现在开始到时间变量”还有多长时间显示时间变量
title
每个单词首字母大写
truncatewords
将字符串转换为省略表达方式
{{ ‘This is a pen’ | truncatewords:2 }}返回This is …
truncatewords_html
同上,但保留其中的HTML标签
{{ ‘;p;This is a pen;/p;’ | truncatewords:2 }}返回;p;This is …;/p;
urlencode
将字符串中的特殊字符转换为url兼容表达方式
{{ ‘http://www.aaa.com/foo?a=b&b=c ’ | urlencode}}
urlize
将变量字符串中的url由纯文本变为链接
wordcount
返回变量字符串中的单词数
yesno
将布尔变量转换为字符串yes, no 或maybe
{{ True | yesno }}{{ False | yesno }}{{ None | yesno }} 返回 yesno maybe
# 应用导出
python manage.py dumpdata [ appname] > appname_data.json
# 应用导出的某一张表
python manage.py dumpdata [ appname.table] > appname_data.json
# 导入
python manage.py loaddata blog_dump.json blog_dump2.json blog_dump3.json
django集成redis
环境准备
apt install redis
pip install django-redis
setting 中添加配置
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://127.0.0.1:6379/1",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
}
}
}
django集成 celery flower
celery详细说明
Celery之前的版本需要一个单独的库才能与Django一起使用,但是自3.1之后就不再是这种情况了。
Django现在是开箱使用的,
pip install Celery "celery[redis,auth,msgpack]"
前提条件 已有 redis
setting 中添加配置
CELERY_BROKER_URL = 'redis://localhost:6379/0'
CELERY_RESULT_BACKEND = 'redis://localhost:6379/1'
CELERY_ACCEPT_CONTENT = ['application/json']
CELERY_RESULT_SERIALIZER = 'json'
CELERY_TIMEZONE = "Asia/Shanghai"
CELERY_MAX_TASKS_PER_CHILD = 100
CELERY_LOG_FILE = os.path.join(BASE_DIR,'celery.log')
CELERYBEAT_LOG_FILE = os.path.join(BASE_DIR,'celery.log.beta')
在app 下创建 celery.py
import os
from celery import Celery
# Set the default Django settings module for the 'celery' program.
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'Assetinventory.settings') # 注意自己的 setting
app = Celery('tech') # 注意替换app
# Using a string here means the worker doesn't have to serialize
# the configuration object to child processes.
# - namespace='CELERY' means all celery-related configuration keys
# should have a `CELERY_` prefix.
app.config_from_object('django.conf:settings', namespace='CELERY')
# Load task modules from all registered Django apps.
app.autodiscover_tasks() # 自动遍历目录下的tasks.py
@app.task(bind=True, ignore_result=True)
def debug_task(self):
print(f'Request: {self.request!r}')
新建tasks.py
from celery import shared_task
from .about_qiwei import wxsendmsg
@shared_task
def shared_task_demo(username,txt):
print('shared_task_demo')
wxsendmsg(username,txt)
在正常代码中的调用方式 delay
shared_task_demo.delay(c.userinfo_obj.username,txt=f"{request.user.first_name}申请使用你在用的设备")
启动:
celery -A tasks flower --broker=redis://@loaclhost:6379/0
celery --app tasks worker --loglevel=info
DJANGO_SETTING_MODULE=setting.loacl celery --app tasks worker --loglevel=info
定时任务
>> 方法如下
@shared_task
def check_our_dev():
check_devalive()
>> setting使用下面的
CELERY_BEAT_SCHEDULE = {
'run-every-minute': {
'task': 'tech.tasks.check_our_dev',
'schedule': 60.0, # 每分钟执行一次
},
}
坑
异步任务无法保存数据库
事务 是将一系列数据库操作作为原子操作执行的机制,要么全部成功提交,要么全部回滚。
在Django中,默认情况下,每个同步请求都会自动启动一个数据库事务,并在请求结束时进行提交。
但是,在异步任务中,默认情况下不会自动启动事务,因此需要手动管理事务。
django.db.transaction模块提供了在Django中进行数据库事务处理的功能
from django.db import transaction
# 使用上下文管理器
def your_task_function():
with transaction.atomic():
# 执行数据库操作
# 如果发生异常,事务将回滚
# 或者装饰器
@transaction.atomic
def your_task_function():
# 执行数据库操作
# 如果发生异常,事务将回滚