一、ORM操作进阶

ForeignKey关联

示例models

from django.db import models
# Create your models here.
class User(models.Model):
name = models.CharField(max_length=32) class Host(models.Model):
host_name = models.CharField(max_length=32)
blong_to = models.ForeignKey("User")

ForeignKey创建数据

models.Host.objects.create(host_name="127.0.0.1",blong_to=models.User.objects.get(id=1))

1、搜索条件使用 __ 连接  2、获取值时使用 . 连接

user_list=models.Host.objects.filter(blong_to__name="lisi")    #一对多过滤条件

for item in user_list:
print(item.host_name,item.blong_to.name) #取数据,在前端取数据也类似

ForeignKey修改数据

hosts=models.Host.objects.get(host_name="127.0.0.1")
users=models.User.objects.get(id=2) hosts.blong_to=users
hosts.save()

反向关联查询

user_obj=models.User.objects.get(id=2)
print(user_obj.host_set.select_related())

ManyToManyField关联

示例models

class UserInfo(models.Model):
name = models.CharField(max_length=32)
email = models.CharField(max_length=32)
address = models.CharField(max_length=128) class UserGroup(models.Model):
caption = models.CharField(max_length=64)
user_info = models.ManyToManyField('UserInfo')

ManyToManyField操作(_set是多对多中的固定搭配)

    user_info_obj = models.UserInfo.objects.get(name="zhangsan")
user_info_objs = models.UserInfo.objects.all() group_obj = models.UserGroup.objects.get(caption='CEO')
group_objs = models.UserGroup.objects.all() # 添加数据
#group_obj.user_info.add(user_info_obj)
#group_obj.user_info.add(*user_info_objs)
#
#user_info_obj.usergroup_set.add(group_obj)
#user_info_obj.usergroup_set.add(*group_objs) # 删除数据
#group_obj.user_info.remove(user_info_obj)
#group_obj.user_info.remove(*user_info_objs)
#
#user_info_obj.usergroup_set.remove(group_obj)
#user_info_obj.usergroup_set.remove(*group_objs) # 获取数据
#print group_obj.user_info.all()
#print group_obj.user_info.all().filter(id=1)
#
#print user_info_obj.usergroup_set.all()
#print user_info_obj.usergroup_set.all().filter(caption='CEO')

 F  对同一表内不同的字段进行对比查询

class Entry(models.Model):
n_comments = models.IntegerField()
n_pingbacks = models.IntegerField()
rating = models.IntegerField()
from django.db.models import F
models.Entry.objects.filter(n_comments__gt=F('n_pingbacks'))
models.Entry.objects.filter(n_comments__gt=F('n_pingbacks') * 2)
models.Entry.objects.filter(rating__lt=F('n_comments') + F('n_pingbacks'))

批量自增

models.Entry.objects.all().update(n_pingbacks=F('n_pingbacks') + 1)

 

Q  构建搜索条件

from django.db.models import Q

models.UserInfo.objects.get(
Q(name='zhangsan'),Q(email="12345678@qq.com")) #两个都要满足
models.UserInfo.objects.get(
Q(name='zhangsan') | Q(email="12345678@qq.com")) #只需满足一个
models.UserInfo.objects.get(
Q(name='zhangsan'),Q(email="12345678@qq.com") | Q(address="abcde"))

django 实现分页

实例

#!/usr/bin/env python
# -*- coding:utf-8 -*-
from django.shortcuts import render,HttpResponse
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from app01 import models
# Create your views here.
def stu_login(request):
return render(request,"app01/login.html") def stu_home(request):
customer_list=models.Customer.objects.all()
paginator = Paginator(customer_list, 1) #每页显示条数 page = request.GET.get('page')
try:
contacts = paginator.page(page)
except PageNotAnInteger:
# If page is not an integer, deliver first page.
contacts = paginator.page(1)
except EmptyPage:
# If page is out of range (e.g. 9999), deliver last page of results.
contacts = paginator.page(paginator.num_pages) return render(request, "app01/home.html", {"customer_list":contacts})

views

    <div class="pagination">
<nav>
<ul class="pagination">
{% if customer_list.has_previous %}
<li class=""><a href="?page={{ customer_list.previous_page_number }}" aria-label="Previous"><span aria-hidden="true">&laquo;</span></a></li>
{% endif %}
{% for page_num in customer_list.paginator.page_range %}
{% if page_num == customer_list.number %}<!--如果page_num是当前选中的页-->
<li class="active"><a href="?page={{ page_num }}">{{ page_num }} <span class="sr-only">(current)</span></a></li>
{% else %}
<li class=""><a href="?page={{ page_num }}">{{ page_num }} <span class="sr-only">(current)</span></a></li>
{% endif %}
{% endfor %}
{% if customer_list.has_next %}
<li class=""><a href="?page={{ customer_list.next_page_number }}" aria-label="Next"><span aria-hidden="true">&raquo;</span></a></li>
{% endif %}
</ul>
</nav>
</div>

html

优化:固定页码个数

1、自定义template tags

  

#!/usr/bin/env python
# -*- coding:utf-8 -*-
from django import template
from django.utils.safestring import mark_safe register = template.Library() @register.simple_tag
def custemer_paging(current_page,loop_num): #传入选中页和循环页
num_left=current_page-2
num_right=current_page+2
if loop_num>num_left and loop_num<num_right:#只显示3页
if current_page == loop_num:
result='''<li class="active"><a href="?page=%s">%s <span class="sr-only">(current)</span></a></li>'''%(loop_num,loop_num)
else:
result='''<li class=""><a href="?page=%s">%s <span class="sr-only">(current)</span></a></li>'''%(loop_num,loop_num)
return mark_safe(result)
result=""
return mark_safe(result)

custemer_tags.py

在html开头导入

{% load custemer_tags %}

使用自定义simple_tag

    <div class="pagination">
<nav>
<ul class="pagination">
{% if customer_list.has_previous %}
<li class=""><a href="?page={{ customer_list.previous_page_number }}" aria-label="Previous"><span aria-hidden="true">&laquo;</span></a></li>
{% endif %}
{% for page_num in customer_list.paginator.page_range %} {% custemer_paging customer_list.number page_num %}<!--使用custemer_tags--> {% endfor %}
{% if customer_list.has_next %}
<li class=""><a href="?page={{ customer_list.next_page_number }}" aria-label="Next"><span aria-hidden="true">&raquo;</span></a></li>
{% endif %}
</ul>
</nav>
</div>

更多详情:https://docs.djangoproject.com/en/1.9/topics/pagination/

三、在自己写的脚本里调用django models

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import os
os.environ['DJANGO_SETTINGS_MODULE'] = 'django_project.settings'
import django
django.setup() from app01 import models result = models.UserInfo.objects.get(id=1)
print(result)

四、用户认证

from django.contrib.auth.models import User

class UserProfile(models.Model):
user = models.OneToOneField(User)
name = models.CharField(max_length=32)
from django.contrib.auth import authenticate,login,logout
from django.contrib.auth.decorators import login_required @login_required
def acc_home(request):
return render(request,"index.html") def acc_login(request):
if request.method == "POST":
username = request.POST.get("username")
password = request.POST.get("password")
user = authenticate(username=username,password=password) #验证 if user is not None:
login(request,user) #登录
return redirect("/app01/acc_home/")
else:
return render(request,"login.html") def acc_logout(request):
logout(request) #退出

在前端显示用户名或对应的名字

    <div>
{% if request.user.is_authenticated %} <!--如果已经登录-->
<span>{{ request.user }}</span> <!--用户名-->
<span>{{ request.user.userprofile.name }}</span> <!--用户名在UserProfile表对应的名字-->
{% endif %}
</div>

五、权限管理

django 自带有基本的权限管理 ,但粒度和限制权限的维度都只是针对具体的表

自己写的权限要易扩展、灵活,权限系统的设计对开发者、用户要实现透明,即他们不需要改变自己原有的使用系统或调用接口的方式,权限要能实现非常小的粒度的控制,甚至细致到一个按键某个用户是否能按。

想对一个功能实现权限控制,要做到只需在views方法上加一个装饰器就行了

例:

在表内创建一个class Meta,自己定义几个权限。

class UserProfile(models.Model):
user = models.OneToOneField(User)
name = models.CharField(verbose_name=u"姓名",max_length=32)
def __unicode__(self):
return self.name
class Meta:
permissions = (("view_customer_list",u"查看客户信息"),
("view_customer_info",u"查看客户详细信息"),
("view_customer_updata",u"修改详细信息"),
)

python manage.py makemigrations
python manage.py migrate

关联动作

这里创建一个permissions.py,创建check_permission装饰器

 #!/usr/bin/env python
# -*- coding:utf-8 -*-
from django.core.urlresolvers import resolve
from django.shortcuts import render
perm_dic = {
"view_customer_list":["customer_list","GET",[]],
"view_customer_info":["customer_info","GET",[]],
"view_customer_updata":["customer_info","POST",[]],
} def perm_check(*args,**kwargs):
request = args[0]
url_resovle_obj = resolve(request.path_info)
current_url_namespace = url_resovle_obj.url_name
#app_name = url_resovle_obj.app_name #use this name later
print("url namespace:",current_url_namespace)
matched_flag = False # find matched perm item
matched_perm_key = None
if current_url_namespace is not None:#if didn't set the url namespace, permission doesn't work
print("find perm...")
for perm_key in perm_dic:
perm_val = perm_dic[perm_key]
if len(perm_val) == 3:#otherwise invalid perm data format
url_namespace,request_method,request_args = perm_val
print(url_namespace,current_url_namespace)
if url_namespace == current_url_namespace: #matched the url
if request.method == request_method:#matched request method
if not request_args:#if empty , pass
matched_flag = True
matched_perm_key = perm_key
print('mtched...')
break #no need looking for other perms
else:
for request_arg in request_args: #might has many args
request_method_func = getattr(request,request_method) #get or post mostly
#print("----->>>",request_method_func.get(request_arg))
if request_method_func.get(request_arg) is not None:
matched_flag = True # the arg in set in perm item must be provided in request data
else:
matched_flag = False
print("request arg [%s] not matched" % request_arg)
break #no need go further
if matched_flag == True: # means passed permission check ,no need check others
print("--passed permission check--")
matched_perm_key = perm_key
break else:#permission doesn't work
return True if matched_flag == True:
#pass permission check
perm_str = "app01.%s" %(matched_perm_key)
if request.user.has_perm(perm_str):
print("\033[42;1m--------passed permission check----\033[0m")
return True
else:
print("\033[41;1m ----- no permission ----\033[0m")
print(request.user,perm_str)
return False
else:
print("\033[41;1m ----- no matched permission ----\033[0m") def check_permission(func):
def wrapper(*args,**kwargs):
print("---start check perms",args[0])
if not perm_check(*args,**kwargs):
return render(args[0],'app01/403.html')
return func(*args,**kwargs)
#print("---done check perms")
return wrapper

permissions.py

    url(r'^stu_home/$', views.stu_home,name="customer_list"),
url(r'^stu_detail/(\d+)/$', views.stu_detail,name="customer_info"),

在views导入自己写的装饰器并在相应方法上加一个装饰器

可以用超级用户通过admin对普通用户进行权限控制

六、CSRF(跨站域请求伪造)

CSRF(Cross Site Request Forgery, 跨站域请求伪造)是一种网络的攻击方式,它在 2007 年曾被列为互联网 20 大安全隐患之一

防御策略

  在请求地址中添加 token 并验证

Django 中使用CSRF,在表单下使用{% csrf_token %}

<form action="" method="post">{% csrf_token %}

  

AJAX中CSRF

function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie != '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) == (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
var csrftoken = getCookie('csrftoken'); function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
});

Django进阶2的更多相关文章

  1. Python之路,Day16 - Django 进阶

    Python之路,Day16 - Django 进阶   本节内容 自定义template tags 中间件 CRSF 权限管理 分页 Django分页 https://docs.djangoproj ...

  2. django进阶补充

    前言: 这篇博客对上篇博客django进阶作下补充. 一.效果图 前端界面较简单(丑),有两个功能: 从数据库中取出书名 eg: 新书A 在form表单输入书名,选择出版社,选择作者(多选),输入完毕 ...

  3. django进阶-3

    先看效果图: 登陆admin后的界面: 查看作者: 当然你也可以定制admin, 使界面更牛逼 数据库表结构: app01/models.py from django.db import models ...

  4. django进阶-4

    前言: 下篇博客写关于bootstrap... 一.如何在脚本测试django from django.db import models class Blog(models.Model): name ...

  5. Django进阶篇【1】

    注:本篇是Django进阶篇章,适合人群:有Django基础,关于Django基础篇,将在下一章节中补充! 首先我们一起了解下Django整个请求生命周期: Django 请求流程,生命周期: 路由部 ...

  6. Django进阶知识

    drf学习之Django进阶点 一.Django migrations原理 1.makemigrattions: 相当于在每个app下的migrations文件夹下生成一个py脚本文件用于创建表或则修 ...

  7. django进阶-查询(适合GET4以上人群阅读)

    前言: 下篇博客写关于bootstrap... 一.如何在脚本测试django from django.db import models class Blog(models.Model): name ...

  8. django进阶-modelform&admin action

    先看效果图: 登陆admin后的界面: 查看作者: 当然你也可以定制admin, 使界面更牛逼 数据库表结构: app01/models.py from django.db import models ...

  9. django进阶-小实例

    前言: 这篇博客对上篇博客django进阶作下补充. 一.效果图 前端界面较简单(丑),有两个功能: 从数据库中取出书名 eg: 新书A 在form表单输入书名,选择出版社,选择作者(多选),输入完毕 ...

  10. django进阶-1

    前言: 各位久等了,django进阶篇来了. 一.get与post 接口规范: url不能写动词,只能写名词 django默认只支持两种方式: get, post get是获取数据 ?user=zcl ...

随机推荐

  1. 前端开发自学之JavaScript——显示当前时间

    <html> <head> <title>JavaScript</title> <script language="javascript ...

  2. Linux分区方案 (转)

    以下是我的centOS6.2系统分区方案,做个记录,方便后续的参考. 根分区: >= 3G /boot (启动分区): 100M即可. /swap : 网上说是物理内存的两倍,实际随便你,看自己 ...

  3. ORM系列之二:EF(5) Model First

    前面我们已经介绍过EF中Code First开发模式,简而言之,就是不管三七二十一直接写代码,不过对于很多开发人员来说,可能并不习惯这样来开发,并且安装标准的开发流程,应该是先建模再进行编码,当然EF ...

  4. 纯CSS实现下拉菜单及下拉容器等(纯CSS实现导航条及导航下拉容器)

    虽然网上类似甚至相同的案例有很多,但是我还是写下,以记下笔记,也可供大家参考 希望大家可以指导批评~~ 首先我们以列表ul li 来开始我们菜单也可以说导航条的制作: 在页面中我们首先构建以下XHTM ...

  5. tar命令实用介绍

    tar -c: 建立压缩档案-x:解压-t:查看内容-r:向压缩归档文件末尾追加文件-u:更新原压缩包中的文件 这五个是独立的命令,压缩解压都要用到其中一个,可以和别的命令连用但只能用其中一个.下面的 ...

  6. SQL 随记

    内连接 select e.empno as 员工编号, e.ename as 员工名字, d.dname as 部门名字from emp e inner join dept d on e.deptno ...

  7. MVC中的数据注解和验证

    数据注解和验证 用户输入验证在客户端浏览器中需要执行验证逻辑. 在客户端也需要执行. 注解是一种通用机制, 可以用来向框架注入元数据, 同时, 框架不只驱动元数据的验证, 还可以在生成显示和编辑模型的 ...

  8. 百度地图坐标纠偏和转换工具和DLL

    百度一直以来都是个即想装出一副拥抱互联网开放的样子,又为了短期商业利益封闭自己的公司,模仿谷歌地图,开放了自己的百度地图 API,为了防止别人盗用其数据和用户自由迁移,地图相比于火星坐标,又更加封闭, ...

  9. noi 1.5 43:质因数分解

    描述 已知正整数 n 是两个不同的质数的乘积,试求出较大的那个质数. 输入 输入只有一行,包含一个正整数 n.对于60%的数据,6 ≤ n ≤ 1000.对于100%的数据,6 ≤ n ≤ 2*10^ ...

  10. Leetcode: Matchsticks to Square && Grammar: reverse an primative array

    Remember the story of Little Match Girl? By now, you know exactly what matchsticks the little match ...