加载模板
django.template.loader这个模块提供了两种方法加载模板
- 加载指定模板并返回Template对象
get_template(template_name,using=None)
- 它与get_template类似,它尝试每个名称并返回第一个存在的模板
select_template(template_name_list,using=None)
- 从文件加载内容
from django.template import Context.loader
def index(request):
t=loader.get_template("test.html")
context={'name':'hello world'}
return HttpResponse(t.render(context,request)) #render的作用是一行一行读取模板的内容,然后替换掉{{}}里面的内容
模板的快捷方式 render() 这是封装之后的
from django.shortcuts import render
def index(request):
context={'name':'reboot'}
return render(request,'test.html',context)
修改密码
Django 不会在user模型上存储原始的(明文)密码,而只是一个哈希,因为这个原因,不要尝试直接操作user的password属性,这也是为什么创建一个user时要使用辅助函数。
from django.contrib.auth.models import User
u=User.objects.get(username='rock')
u.set_password('654321')
u.save()
补充:form表单默认提交数据的方式为urlencoded编码,只要是urlencoded编码,http请求的body体中的数据为k1=value1&k2=value2,Django框架会从body体里面把数据拿出来放到POST里面。这时我们只需要通过request.POST.get(‘XXX’)就可以了
如果我们指定编码格式为json格式:Http请求的body体里面的数据格式为:"{“key1”:“value1”,“key2”:“value2”},这个时候Django框架不会给我们处理,需要我们后台来处理,将处理好的数据放到POST里面. json_dict=json.loads(request.body) request.POST=json_dict
前端部分代码:
<body>
<p>用户名:<input type="text" id="name"></p>
<p>pwd:<input type="text" id="pwd"></p>
<button id="btn">提交</button>
$("#btn").click(function () {
$.ajax({
url: '/login/',
type: 'post',
//contentType:'application/json',
//把字典类型转成字符串
//data:JSON.stringify({name:$("#name").val(),pwd:$("#pwd").val()}), #在body体里面"{"name":"xxx","age":"15"}"
data: {name: $("#name").val(), pwd: $("#pwd").val()},
success: function (data) {
console.log(data)
}
})
})
def outer(func):
'''
只能用来装饰视图函数
:param func:
:return:
'''
def inner(request, *args, **kwargs):
# args[0].POST=json.loads(args[0].body)
# 是为了防止报错,主要是处理urlencode这种编码,这种编码应该不处理
try:
# name=lqz&pwd=123
request.POST = json.loads(request.body)
except Exception as e:
print(e)
ret = func(request, *args, **kwargs)
return ret
return inner
@outer
def login(request):
if request.method == 'GET':
return render(request, 'login.html')
if request.is_ajax():
print(request.body) #type 'bytes'
print(request.POST)
# loads可以直接传二进制
# request_dic=json.loads(request.body)
# request.POST=request_dic
# print(type(request_dic))
name = request.POST.get('name')
pwd = request.POST.get('pwd')
print(name)
print(pwd)
return HttpResponse('ok')
视图
路由
url参数–额外参数
数据分页
主url:
url(r'^dashboard/', include("dashboard.urls")),
app urls:
url(r'^hello/', views.my_view),
url(r'^hellot/',views.MyView.as_view()),
def my_view(request,*args,**kwargs):
username='rock'
for i in range(1000):
name="{}_{}".format(username,i)
User.objects.create_user(name,"{}@51reboot.com".format(name),'123456')
return HttpResponse("hello")
class MyView(View):
def get(self,request,*args,**kwargs):
per=10
try:
page=int(request.GET.get("page",1))
except:
page=1
end=page*10
start = end - 10
query_set=User.objects.all()[start:end] #type Queryset
user_list=list(query_set.values('username','email','password')) #type list
return JsonResponse(user_list,safe=False)
访问url:http://127.0.0.1:8000/dashboard/hellot/?page=100
分页
- Paginator 对象
class Paginator(object_list, per_page, orphans=0, allow_empty_first_page=True)
Required arguments
- object_list
- per_page
Optional arguments
- orphans
- allow_empty_Òrst_page
属性
- Paginator.count 所有页面的objects总数
- Paginator.num_pages 页面总数
- Paginator.page_range 页码的范围,从1开始,例如[1, 2, 3, 4]
方法
- Paginator.page(number) 返回一个page对象,number, 当前显示的是第几页
def index(request):
user_list=User.objects.all()
paginator=Paginator(user_list,10)
print('count:',paginator.count) #数据总数
print('num_pages:',paginator.num_pages) #总页数
print('page_range',paginator.page_range) #页数范围
page=paginator.page(10) #第10页的page对象
print("当前页数:",page.number)
# for i in page:
# print(i)
print(page.object_list) #第10页的所有数据
class Page(object_list, number, paginator)
属性
- Page.object_list 当前页面的对象列表
- Page.number 当前页的序号,从1开始
- Page.paginator Paginator对象
方法
- Page.has_next() 如果有下一页,返回True
- Page.has_previous() 如果有上一页,返回 True
- Page.has_other_pages() 如果有上一面或下一页,返回True
- Page.next_page_number() 返回下一页的页码。如果不存在,抛出InvalidPage异常
- Page.previous_page_number() 返回上一页的页码。如果不存在,抛出InvalidPage异常
- Page.start_index() 返回当前页上的第一个对象,相对于分页列表的所有对象的序号
- Page.end_index() 返回当前页上的最后一个对象,相对于分页列表的所有对象的序号
def index(request):
user_list=User.objects.all()
paginator=Paginator(user_list,10)
page2=paginator.page(101) #第101页的数据对象
print(page2.has_next()) #是否有下一页
# print(page2.next_page_number()) #下一页的页码
print(page2.has_previous()) #是否有上一页
print(page2.previous_page_number()) #上一页的页码
- 抛错
#page=paginator.page(101) # error:EmptyPage
#page=paginator.page("z") # error:PageNotAnInteger
user_list=User.objects.all()
paginator = Paginator(user_list, 10)
page = request.GET.get('page',1)
currentPage=int(page)
try:
print(page)
user_list = paginator.page(page) #当前页的数据对象
except PageNotAnInteger:
user_list = paginator.page(1)
except EmptyPage:
user_list = paginator.page(paginator.num_pages) #最后一页的数据对象
Django日志
Django 使用Python 内建的logging 模块打印日志,Python 的logging 配置由四个部分组成:
- 记录器–Logger
- 处理程序–Handler
- 过滤器–Filter
- 格式化–Formatter
记录器–Logger
- Logger 为日志系统的入口。每个logger命名都是bucket,你可以向这个bucket写入需要处
理的消息。 - 每个logger 都有一个日志级别。日志级别表示该logger 将要处理的消息的严重性。Python
定义以下几种日志级别
DEBUG:用于调试目的的底层系统信息
INFO:普通的系统信息
WARNING:表示出现一个较小的问题。
ERROR:表示出现一个较大的问题。
CRITICAL:表示出现一个致命的问题。
写入logger 的每条消息都是一条日志。每条日志也具有一个日志级别,它表示对应的消息
的严重性。每个日志记录还可以包含描述正在打印的事件的元信息。当一条消息传递给logger 时,消息的日志级别将与logger 的日志级别进行比较。如果消息
的日志级别大于等于logger 的日志级别,该消息将会往下继续处理。如果小于,该消息将
被忽略。Logger 一旦决定消息需要处理,它将传递该消息给一个Handler。
logger 日志级别
Logger配置
logger 对应的值是个字典,其每一个键都是logger的名字,每一个值又是个字典,描述了如何
配置对应的Logger实例。
- level (可选的)。logger的级别。
- propagate (可选的)。logger的传播设置。propagate :True 要向上级传递,
- Òlters (可选的)。logger的Òlter的标识符的列表。
- handlers (可选的)。logger的handler的标识符的列表。
Logger配置示例
LOGGING = {
'loggers': {
'reboot': {
'handlers': ['file_handler', 'console_handler'],
'level': 'DEBUG',
},
},
}
过滤器——Filters
- Filter 用于对从logger 传递给handler 的日志记录进行额外的控制。
- 默认情况下,满足日志级别的任何消息都将被处理。通过安装一个Òlter,你可以对日志处
理添加额外的条件。例如,你可以安装一个Òlter,只允许处理来自特定源的ERROR 消息 - Filters 还可以用于修改将要处理的日志记录的优先级。例如,如果日志记录满足特定的条
件,你可以编写一个Òlter 将日志记录从ERROR 降为WARNING - Filters 可以安装在logger 上或者handler 上;多个Òlter 可以串联起来实现多层Òlter 行为
格式化——Formatters
最后,日志记录需要转换成文本。Formatter 表示文本的格式。Fomatter 通常由包含日志记录
属性的Python 格式字符串组成;你也可以编写自定义的fomatter 来实现自己的格式
LOGGING = {
'formatters': {
'reboot':{
'format': '%(asctime)s - %(pathname)s:%(lineno)d[%(levelname)s] - %(message)s'
}'
simple': {
'format': '%(asctime)s %(levelname)s %(message)s'
},
},
}
Format 日志消息格式
Django 内置logger
- django 获取所有日志
- django.request 处理与请求相关的日志,5xx响应报出error日志,4xx报出WARNING日志
- django.db.backends 处理与数据库之间交互的日志,
- django.security.* 处理与安全相关的日志
- django.db.backends.schemea 处理数据库迁移时的日志
settings.py:
LOGGING = {
'version': 1,
'disable_existing_loggers': True,
'formatters': {
'standard': {
'format': '%(asctime)s - %(lineno)s- %(levelname)s- %(message)s'} #日志格式
},
'filters': {
},
'handlers': {
'console':{
'level':'DEBUG',
'class':'logging.StreamHandler',
'formatter':'standard'
},
'file':{
'level':'DEBUG',
'class':'logging.FileHandler',
'filename':os.path.join(BASE_DIR,"xxx_info.log"),
'formatter': 'standard'
}
},
'loggers': {
'reboot': {
'handlers': ['console','file'],
'level': 'DEBUG',
},
}
}
views.py
import logging
logger=logging.getLogger('reboot')
logger.debug("这是一条DBUG日志")