1.前后台的数据传递
view -> HTML:使用Django模版
views.py代码:
from django.shortcuts import render def main_page(request): data = [1,2,3,4] return render(request, 'index.html', {'data': data})
HTML中用 {{}} 获取数据
<div>{{ data }}</div>
可以对可迭代的数据进行迭代:
{% for item in data%} <p>{{ item }}</p> {% endfor %}
该方法可以传递各种数据类型,包括list,dict等等。
2.与数据库交互并返回数据的几种比较常用的方法
models.UserInfo.objects.all() models.UserInfo.objects.all().values('user') #只取user列 models.UserInfo.objects.all().values_list('id','user') #取出id和user列,并生成一个列表 models.UserInfo.objects.get(id=1) models.UserInfo.objects.get(user='cucucu')
3.一个表单对应多个按钮解决方案
为不同按钮添加不同name属性,然后再后台判断name值
<form method="post" action="自定" οnsubmit="return"> <button type="submit" class="btn btn-info" name="del">删除</button> <button type="submit" class="btn btn-info" name="update">更新</button> </form>
然后通过不同的name实现不同功能
def function(request): if request.POST: if 'update' in request.POST: ... #update功能实现 else: ... #del功能实现 return render(request, 'xxx.html', yyy)
4.HTML中的表单控件及操作
在HTML中表单的书写一般为:
<form method="post" action=""> <!-这个method代表方法,方法一般有两个一个是'post',一个是'get',action是提交表单到何处,可填写一个网址。不填则默认到本页面。> {%csrf_token%} <!-这个是django中的一个标签,用于防止恶意攻击使用,如果不加入这个标签,会遇到不能提交的问题,处理麻烦一点,建议加上。> <input name="select" type="radio" value='radio'> <!-这就是一个单选标签,多选为type='checkbox'。 value是显示的内容,并且后端提交后也将此作为值,其中name是后端获取时所用的如后端使用 select = request.POST['select']获取这个单选按钮的value,另外也可以用select = request.POST.get('select',None)来获取。> <input name="submit" type="submit" value="提交" /> <!-这就是一个提控件,其中的type='submit'会保证点击后表单(<form></form>)中的内容被提交到后端。> <input name="text" type="text" value="" /> <!-一个输入框> </form> <!-表单结束>
前端HTML代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form method="post" action=""> {%csrf_token%} <input name="select" type="radio" value='radio'> <input name="text" type="text" value="" /> <input name="submit" type="submit" value="提交" /> </form> </body> </html>
后端在views.py中书写一个函数接受前端传入的数据:
def receive_data(request): if request.POST: # 如果数据提交 print('有提交') select = request.POST.get('select',None) text = request.POST.get('text',None) print(select,text) return render(request,'your_html.html', locals()) # your_html.html改为你的html页面并且参考前面的博客建立url链接。
5.消息框架 message使用
消息级别:
该功能运用了django.contrib.messages这个库,在django项目中setting.py文件中APP注册部分自定义注册
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'app01.apps.App01Config', # 自定义APP注册 ]
后端views.py中
from django.contrib import messages def abc(request): messages.debug(request, '%s SQL statements were executed.' % count) messages.info(request, 'Three credits remain in your account.') messages.success(request, 'Profile details updated.') messages.warning(request, 'Your account expires in three days.') messages.error(request, 'Document deleted.')
或者
from django.contrib import messages def abc(request): messages.add_message(request, messages.INFO, 'Hello world.')
前端显示
{% if messages %} <script> {% for msg in messages %} alert('{{ msg.message }}'); {% endfor %} </script> {% endif %}
6.日期和时间DateField的auto_now、auto_now_add
创建django的model时,有DateTimeField、DateField和TimeField三种类型可以用来创建日期字段,其值分别对应着datetime()、date()、time()三中对象,这三个field有着相同的参数auto_now和auto_now_add。
auto_now:
这个参数的默认值为false,设置为true时,能够在保存该字段时,将其值设置为当前时间,并且每次修改model,都会自动更新。因此这个参数在需要存储“最后修改时间”的场景下,十分方便。需要注意的是,设置该参数为true时,并不简单地意味着字段的默认值为当前时间,而是指字段会被“强制”更新到当前时间,你无法程序中手动为字段赋值;如果使用django自带的admin管理器,那么该字段在admin中是只读的。
auto_now_add:
设置为True时,会在model对象第一次被创建时,将字段的值设置为创建时的时间,以后修改对象时,字段的值不会再更新。该属性通常被用在存储“创建时间”的场景下。与auto_now类似,auto_now_add也具有强制性,一旦被设置为True,就无法在程序中手动为字段赋值,在admin中字段也会成为只读的。
7.获取已登录用户的名字
在 views里取值是request.user.username
,在模板页面取值是{{request.user}}
,判断是否通过验证是{% if request.user.is_authenticated %}
8.数据库表中属性的自增/自减操作
通过相对更新的操作来更加快速、健壮地实现,而不是显示地(explicit)对新值进行赋值。Django提供了F()表达式 进行相对更新操作
from django.db.models import F product = Product.objects.get(name='Venezuelan Beaver Cheese') product.number_sold = F('number_sold') + 1 product.save()
这种方法没有使用数据库中特定的原始的值,而是当 save() 执行时,让数据库去根据数据库当前的值进行更新操作;
一旦当前对象被存储时,我们必须重新加载当前对象以获取到当前数据库中最新的值。
9.执行原始sql语句
(1)extra()方法:
结果集修改器,一种提供额外查询参数的机制。
Book.objects.filter(publisher__name='广东人员出版社').extra(where=['price>50']) Book.objects.filter(publisher__name='广东人员出版社',price__gt=50) Book.objects.extra(select={'count':'select count(*) from hello_Book'})
(2)raw()方法:
管理器的 raw() 方法可以用于执行原始 SQL 并返回模型实例:
Manager.raw(raw_query, params=None, translations=None)
使用raw:
Book.objects.raw('select * from hello_Book')
自定义sql:
Book.objects.raw("insert into hello_author(name) values('测试')")
rawQuerySet为惰性查询,只有在使用时生会真正执行。
10.分页显示数据
python后端:
urls.py:
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^index1$', views.index1), ]
views.py:
from django.shortcuts import render from django.core.paginator import Paginator,PageNotAnInteger,EmptyPage # Create your views here. #简单的创建出很多的数据来试验 USER_LIST=[] for i in range(1,999): temp={'name':'root'+str(i),'age':i} USER_LIST.append(temp) def index1(request): # 全部数据:USER_LIST,=》得出共有多少条数据 # per_page: 每页显示条目数量 # count: 数据总个数 # num_pages:总页数 # page_range:总页数的索引范围,如: (1,10),(1,200) # page: page对象(是否具有下一页;是否有上一页;) current_page = request.GET.get('p') #当前页码 current_page=int(current_page) # Paginator对象 paginator = Paginator(USER_LIST,10) # 一页放10个数据 #加判断当总页数大于10页 让一部分不显示出来 if paginator.num_pages > 10: if current_page - 5 < 1: posts_list = range(1, 11) elif current_page+ 5 > paginator.num_pages: posts_list = range(current_page - 5, paginator.num_pages + 1) else: posts_list = range(current_page - 5, current_page + 5) else: #当小于等于10页时全部显示 posts_list = paginator.page_range try: # Page对象 posts = paginator.page(current_page) # has_next 是否有下一页 # next_page_number 下一页页码 # has_previous 是否有上一页 # previous_page_number 上一页页码 # object_list 分页之后的数据列表,已经切片好的数据 # number 当前页 # paginator paginator对象 except PageNotAnInteger: posts = paginator.page(1) except EmptyPage: posts = paginator.page(paginator.num_pages) return render(request, 'index1.html', {'posts': posts,"posts_list":posts_list})
前端显示:
index1.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <ul> {% for row in posts.object_list %} <li>{{row.name}}----------------{{row.age}}</li> {% endfor %} </ul> {% if posts.has_previous %} <a href="/index1?p={{posts.previous_page_number}}">上一页</a> {% else %} <a href="#">上一页</a> {%endif%} {% for index in posts_list%} {% if index == posts.number %} <a href="#" style="color: black">{{index}}</a> {% else %} <a href="/index1?p={{index}}">{{index}}</a> {% endif %} {% endfor %} {% if posts.has_next %} <a href="/index1?p={{posts.next_page_number}}">下一页</a> {% else %} <a href="#">下一页</a> {%endif%} <span> {{posts.number}}/{{posts.paginator.num_pages}} </span> </body> </html>