django  Pagination(分页)

django 自带的分页功能非常强大,我们来看一个简单的练习示例:

#导入Paginator
>>> from django.core.paginator import Paginator
#处理的对象
>>> objects = ['john', 'paul', 'george', 'ringo']
#实例化类,传入对象,每页显示条数
>>> p = Paginator(objects, )
#查看总数据条数
>>> p.count
4
#查看总页数
>>> p.num_pages >>> type(p.page_range) # `<type 'rangeiterator'>` in Python .
<class 'range_iterator'>
#返回一个包含当前页数的迭代器
>>> p.page_range
range(, )
#获取第一页的数据
>>> page1 = p.page()
>>> page1
<Page of >
#显示数据
>>> page1.object_list
['john', 'paul']
#获取第二页的数据
>>> page2 = p.page()
#显示数据
>>> page2.object_list
['george', 'ringo']
#显示当前页
>>> page2.number
2
#获取下一页 返回bool值
>>> page2.has_next()
False
#获取上一页 返回bool值
>>> page2.has_previous()
True
#获取其他页 返回bool值
>>> page2.has_other_pages()
True
#获取下一页页数
>>> page2.next_page_number()
Traceback (most recent call last):
...
EmptyPage: That page contains no results
#获取上一页页数
>>> page2.previous_page_number()
1
#获取当前页第一条数据在总条数的索引
>>> page2.start_index() # The -based index of the first item on this page
3
#获取当前页最后一条数据在总条数的索引
>>> page2.end_index() # The -based index of the last item on this page #获取不存在的页
>>> p.page()
Traceback (most recent call last):
...
EmptyPage: That page number is less than
#获取不在范围内的页
>>> p.page()
Traceback (most recent call last):
...
EmptyPage: That page contains no results

示例

views

from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
def userprofile(requeset):
#处理的数据
user_profile = models.UserProfile.objects.all()
#实例化类 传入参数 处理数据,每页条数
paginator = Paginator(user_profile,)
#获取当前页
page = requeset.GET.get('page')
try:
userprofile_obj = paginator.page(page)
except PageNotAnInteger: #输入非数字转为1
userprofile_obj = paginator.page()
except EmptyPage:#超出页面范围
userprofile_obj = paginator.page(paginator.num_pages)
return render(requeset, 'app01/userprofile.html', {'userprofile': userprofile_obj})

html

{% for contact in contacts %}
{# Each "contact" is a Contact model object. #}
{{ contact.full_name|upper }}<br />
...
{% endfor %} <div class="pagination">
<span class="step-links">
{% if contacts.has_previous %}
<a href="?page={{ contacts.previous_page_number }}">previous</a>
{% endif %} <span class="current">
Page {{ contacts.number }} of {{ contacts.paginator.num_pages }}.
</span> {% if contacts.has_next %}
<a href="?page={{ contacts.next_page_number }}">next</a>
{% endif %}
</span>
</div>

效果:

aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAPQAAAAxCAIAAABiaBOuAAADTUlEQVR4nO2ZsZGrMBRFtydqUS2acRWkaoAWCBgiCiAgZBQzxBSgDSSBJB5G/gt/vc/3zAZeWRb4+fB8kb8MAEz5+u0TAOAuIDdgC+QGbIHcgC2QG7AFcgO2QG7AFsgN2AK5AVsgN2AL5AZsgdyALZAbsAVyA7ZAbsAWyA3YArkBWyA3YAvkBmyB3IAtbyP3PIpH31y7plaiSBBKX3uM9EAy+z00kjojN3rbqX4SbyP3HWglEtkaeYM0jVydfmH9Ru5naiXWwWDVW7ijm7wZHyY3NfRTIkuz1z+fSNl/IZA7j0WVnWr74lEXj7qoJmOMmUdR9rKsC1fBSdpn7b9RZRdV1rINRuZRuMmdmteR8Fn/ePAHXWeGPJd7CwBBi1wDhlTBi9epp94e9Nsttwils2JM2MRp5lE8etV2tgKiXfwTcamN0W0XV7IW7Sif1I0LV8kdSSzaxRZRDtsE+1i3XVGOOhgx8yjKUW/KTnJ94dATF0M00382Q1+UY6oCHUvsCJkltkGrn2yiVU6FO5iQHCtZlVwlI3M7TRf39l1N9qU2xpimck2nqfxL0LnzCEy1Na0mM4+C7LveSDfNGN12/mLYN3Wv76Hc23EJcm8ofQCIgoDXMLLwWVTQStCNmFzhNJacZm6ywmT1jHGfURW0AMidRyS3a6KpjnWx/XlfXQuP9Y16sF/5KJZsX8GU5c8FitQXSid91784vUJoubUSh72WDOU/z9xkTchSW4Y+qhLkzuOoc5M6bjRVpwar+FnvOV1t+14OOPnqX9XJ79w0hz2bOI3szv3vcpPKTvLRqeH8Q+HEdZnbtVsfFfa3jGvCjm8HdxGQytzBoG67IIgHmfsluZMYnJe56QXPb/2yM3cYRbQSGTeUO1PJUi+qdHXegnhYPaZc17mrPrptTxvDRN2eT5JsJPvdEue0XX+U8eXxym5J9JzPGU2sr93FkDJq7YeZJNx0OdwASXZLjs+N3Eehe/h5VHM1aao6SHqTdDtadhvg6U3LH+eGzM2Em7eZwf1A7oD/+QMhuB/IHRGkArTtPw/rn9/BZwO5AVsgN2AL5AZsgdyALZAbsAVyA7ZAbsAWyA3YArkBWyA3YAvkBmyB3IAtkBuwBXIDtnwDHeqopreIeL0AAAAASUVORK5CYII=" alt="" />

自定义分页

分页功能在每个网站都是必要的,对于分页来说,其实就是根据用户的输入计算出应该在数据库表中的起始位置。

1、设定每页显示数据条数

2、用户输入页码(第一页、第二页...)

3、根据设定的每页显示条数和当前页码,计算出需要取数据表的起始位置

4、在数据表中根据起始位置取值,页面上输出数据


需求又来了,需要在页面上显示分页的页面。如:[上一页][1][2][3][4][5][下一页]

1、设定每页显示数据条数

2、用户输入页码(第一页、第二页...)

3、设定显示多少页号

4、获取当前数据总条数

5、根据设定显示多少页号和数据总条数计算出,总页数

6、根据设定的每页显示条数和当前页码,计算出需要取数据表的起始位置

7、在数据表中根据起始位置取值,页面上输出数据

8、输出分页html,如:[上一页][1][2][3][4][5][下一页]

实例:

views

from django.utils.safestring import mark_safe
def try_int(arg,default):
try:
arg = int(arg)
except Exception:
arg = default
return arg class Pageinfo(object):
def __init__(self,page,count,per_item=2):
self.cur_page = page
self.all_count = count
self.per_item = per_item
@property
def start(self):
return (self.cur_page-1)* self.per_item
@property
def end(self):
return self.cur_page * self.per_item
@property
def all_page_count(self):
temp = divmod(self.all_count,self.per_item)
if temp[1] == 0:
all_page_count = temp[0]
else:
all_page_count = temp[0] + 1
return all_page_count def Custompager(baseurl,currentPage,totalpage): #基础页,当前页,总页数
perPager=11
#总页数<11
#0 -- totalpage
#总页数>11
#当前页大于5 currentPage-5 -- currentPage+5
#currentPage+5是否超过总页数,超过总页数,end就是总页数
#当前页小于5 0 -- 11
begin=0
end=0
if totalpage <= 11:
begin=0
end=totalpage
else:
if currentPage>5:
begin=currentPage-5
end=currentPage+5
if end > totalpage:
end=totalpage
else:
begin=0
end=11
pager_list=[]
if currentPage<=1:
first="<a href=''>首页</a>"
else:
first="<a href='%s%d'>首页</a>" % (baseurl,1)
pager_list.append(first) if currentPage<=1:
prev="<a href=''>上一页</a>"
else:
prev="<a href='%s%d'>上一页</a>" % (baseurl,currentPage-1)
pager_list.append(prev) for i in range(begin+1,end+1):
if i == currentPage:
temp="<a href='%s%d' style='color:red;'>%d</a>" % (baseurl,i,i)
else:
temp="<a href='%s%d'>%d</a>" % (baseurl,i,i)
pager_list.append(temp)
if currentPage>=totalpage:
next="<a href='#'>下一页</a>"
else:
next="<a href='%s%d'>下一页</a>" % (baseurl,currentPage+1)
pager_list.append(next)
if currentPage>=totalpage:
last="<a href=''>末页</a>"
else:
last="<a href='%s%d'>末页</a>" % (baseurl,totalpage)
pager_list.append(last)
result=''.join(pager_list)
return mark_safe(result) #把字符串转成html语言
from app01 import common
def indexAuthor(request,page):
page = common.try_int(page,1) #获取当前页
# 0 5 1
# 5 10 2
# 10 15 3
# 15 20 4
baseurl = request.path #获取当前url
count = models.Author.objects.all().count() #获取处理的数据总条数
obj = common.Pageinfo(page, count) #实例化当前页和数据总条数
authors_ret = models.Author.objects.all()[obj.start:obj.end] #显示当前页的数据
page_string = common.Custompager(baseurl, page, obj.all_page_count) #返回分页栏对象 ret = {"AuthorList": authors_ret, 'count':count, "page":page_string}
return render_to_response("app01/Author.html",ret)

html

<style>
#Pageing a{
background-color: #2b669a;
border: 1px solid white;
text-decoration: none;
color: white;
padding: .1em .6em .2em .6em;
}
</style>
<div class="mains">
<table name="Author" class="table table-bordered table-hover">
<thead>
<tr>
<th>选择</th>
<th>ID</th>
<th>作者</th>
<th>邮箱</th>
<th>手机</th>
<th>性别</th>
</tr>
</thead>
<tbody id="tb3">
{% for item in AuthorList %}
<tr>
<td><input type="checkbox" /></td>
<td name="id">{{ item.id }}</td>
<td>{{ item.name }}</td>
<td>{{ item.email }}</td>
<td>{{ item.mobiles }}</td>
<td>{{ item.get_gender_display }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<div>总条数:{{ count }}</div>
<div id="Pageing">
{{ page }}
</div>
</div>

效果:

aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAUQAAABHCAIAAADwa6mLAAAFb0lEQVR4nO2cv2sjRxTH9QeENPkD0qW5citVV+mqgMHFQSBwJoUqkeLcRFVQ4VxjAjakUQqBuYQrDgw6ECkOXBwKRBhsFg7LYGEwFip0YEsgWKzipZB/SCvt7szO29Ho6fthMFrt7NunefvR7K7XzhEAQAS5ZScAAOABMgMgBMgMgBAgMwBCgMwACAEyAyAEyAyAECAzAEKAzAAIATIDIATIDIAQIDMAQoDMAAgBMgMgBMgMgBDuZfY8b+Hqhe9HdVbpqb4tAECLp5lZXTwvgvkNY14AAHiZOc1eKGSIkLdRnSfvTP+MD6vE5fsfpr88dv30oQAQx9NpduJ8SxET7EKTo+JERVZheFQu1ru6WwGwJqS5Zn5cFe+kyum3Fv7+Zq2dYjsA1oKUN8BCiiqeZpvJ3K0Xi+VfX73Ie17+Ral23NcPAYBgNGSOmWlDaxfaG3UVHeoQSdDc8fI7zeFkadjcfbXvB0kfD4D1Qe+aOUSKtellDtH/p+SVj4YaWwAgG72HRmKcn7Yx5hshSmZ9/F2vVMepNgAPLJBZ3TTFmZlHZn8/n99/+mVUv17K7xzjPBuABxY/NBL1OvROzA2t0ES9cPOo/hG0a5vf7x5PTqyDy3qp+P4ytj8A60WOFB7tUPFcXdG0MhP1j2uvN597nvd88/VfPq6XAZhmscwTEmfgxMWorwmOa2YAwAy5kGmKt7LjO8yvSpz8AQCG4E8gARACZAZACJAZACFAZgCEkCOiZ8Xq0tskm6WnscSc1yeaneZOzpB5BZrLwrgczU5zJ2eHZI7qwDtSukPvQp1cFsblaHaaO0eUFZGJFGfm+T6hdxR35tTQ289ZJZ9VjGY+ki5UJ6ozVyYWiJNZMYTW0GQ99CYts5x/a32b62yYRiu8veiMJr3Gg95FpWyW257f6o+JiCi4bvtFvupkURr26tg/ti2gcc2cRc90h0u6XSwn558qp999Qzljmcv+2R0N2idb5Wqh6p+NKOj8Z5Db0adbCnoX2+XqZu2ic0fXrQ9c1WEvTYbV0d9F6kwsoCpzYrfEPS1l6Jeb8/bGy8FXXw/yL/vmMjdviL4cPCxunQxp1H2TOtrb7oBGn6r3i4c9ot45V3VYSmOhOupps2RiAaUbYFGol1BxLyaVTne4ZJrz9sbPjR//KBR/6ZjLPNsq7YBG3QpDtL+33l1e07jT5J+Z0xXFWnXUA7JkYgG2u9lai9kNveLHtpszt8zlk9M7uj5pGEf7t3U7DoiC/tXve2zVme45P6TuVEcxDa5MLJDVzBy/aHi4qARMESSznHllbhz2xkHvnO+WVePgKjA6adcZVfeqkxyQJRMLSJuZtZqtnBllbhx0Ahp138TeytYez+pVn4LWO55ousO47Oo8dWY51GOCZw1mZgs5M8m855/eUnB7lWhycrSPX4huDh/jzN4PM6wOS2ksVuc+1PTPLDKxQCYz8/wmjEOvGFA3SJY5c8i8d965u/9lkuJHi4s2uepufSwUq8/KH/7sBPHn7VrVYSmNteo89pl/wZuJBfgf55weFPWDQL2n4ghqtYxzZpC50p7/R6Q3hwa5Faqfz0aTh0Y4HkHJrDSZVociLM3i2LYA22l2zPBFvZ/6cGE8YmzmvCbRLOzXvDrza+cXaVZvw0wswDMzK34kw6FPhOVA4cpZt4mJxrJf+9WJOc5ZMrEA/gTSlZzXJ5qd5k7OkHkFmsvCuBzNTnMnZ8i8As1lYVyOZqe5kzNkXoHmsjAuR7PT3MnZqswAAAFAZgCEAJkBEAJkBkAIkBkAIUBmAIQAmQEQAmQGQAiQGQAhQGYAhACZARACZAZACJAZACFAZgCEAJkBEAJkBkAIkBkAIfwP6jfXRi8LDloAAAAASUVORK5CYII=" alt="" />

总结,分页时需要做三件事:

  • 创建处理分页数据的类
  • 根据分页数据获取数据
  • 输出分页HTML,即:[上一页][1][2][3][4][5][下一页]

django Custom template tags and filters (simple_tag and filters)

自定义一个template_tag 或 filters 需要遵循以下规则

a.目录结构

在app中创建包(必须是在app中,否则会提示没有注册),名称必须为:templatetags

polls/   #app
__init__.py
models.py
templatetags/ #app下的包或模块
__init__.py
poll_extras.py
views.py
b. 创建任意.py文件 
from django import template 导入模板
from django.utils.html import format_html#这条用作处理将字符串当做标签发送前端
register = template.Library() 注册才能使用
@register.filter
def test_upper(val):
print("--val from template:",val )
return val.upper() @register.simple_tag
def guess_page(current_page,loop_num):
offset = abs(current_page - loop_num)
if offset <3:
if current_page == loop_num:
page_ele = '''<li class="active"><a href="?page=%s">%s</a></li>''' %(loop_num,loop_num)
else:
page_ele = '''<li class=""><a href="?page=%s">%s</a></li>''' %(loop_num,loop_num)
return format_html(page_ele)
else:
return ''
c.在使用自定义simple_tag的html文件中导入之前创建的 xx.py 文件名
{% load xx %} #xx为你定义的文件,不带py
d.使用simple_tag 或 filter
{% item.status|test_upper %}
{% guess_page classlist.number classlist.paginator.num_pages %}

e. 注册app

INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app01',
)

实例:利用simple_tag写分页功能

custom.py

@register.simple_tag
#显示前后3条数据
def get_page(current_page,total_page):
page_html = []
if current_page <= 1:
prev = """<li class="">
<a href="?page=%s" aria-label="Previous">
<span aria-hidden="true">&laquo;</span></a></li>""" % (1, )
else:
prev = """<li class="">
<a href="?page=%s" aria-label="Previous">
<span aria-hidden="true">&laquo;</span></a></li>""" % (current_page-1,)
page_html.append(prev)
for i in range(1, total_page+1):
offset = abs(current_page - i)
if offset < 3:
if current_page == i:
page_ele = '''<li class='active'><a href="?page= %s">%s</a></li>''' % (i, i)
else:
page_ele = '''<li><a href="?page=%s">%s</a></li>''' % (i, i)
page_html.append(page_ele)
else:
page_html = page_html
if current_page >= total_page:
next = """<li class="">
<a href="?page=%s" aria-label="Next">
<span aria-hidden="true">&raquo;</span></a></li>""" % (total_page,)
else:
next = """<li class="">
<a href="?page=%s" aria-label="Next">
<span aria-hidden="true">&raquo;</span></a></li>""" % (current_page+1,)
page_html.append(next)
return format_html(''.join(page_html))

views

def course(requeset):
course_list = models.Course.objects.all()
paginator = Paginator(course_list,1)
page = requeset.GET.get('page')
try:
course_obj = paginator.page(page)
except PageNotAnInteger:
course_obj = paginator.page(1)
except EmptyPage:
course_obj = paginator.page(paginator.num_pages)
return render(requeset, 'app01/course.html', {'course_list': course_obj})

html

    <div class="pagination">
<nav>
<ul class="pagination">
{% get_page course_list.number course_list.paginator.num_pages %}
</ul>
</nav>
</div>

Django权限机制的实现

Django权限机制概述

权限机制能够约束用户行为,控制页面的显示内容,也能使API更加安全和灵活;用好权限机制,能让系统更加强大和健壮。因此,基于Django的开发,理清Django权限机制是非常必要的。

Django的权限控制

Django用user, group和permission完成了权限机制,这个权限机制是将属于model的某个permission赋予user或group,可以理解为全局的权限,即如果用户A对数据模型(model)B有可写权限,那么A能修改model B的所有实例(objects)。

group的权限也是如此,如果为group C 赋予model B的可写权限,则隶属于group C 的所有用户,都可以修改model B的所有实例。

这种权限机制只能解决一些简单的应用需求,而大部分应用场景下,需要更细分的权限机制。以博客系统为例,博客系统的用户可分为『管理员』、『编辑』、『作者』和『读者』四个用户组;博客系统管理员和编辑具有查看、修改和删除所有的文章的权限,

作者只能修改和删除自己写的文章,而读者则只有阅读权限。管理员、编辑和读者的权限,我们可以用全局权限做控制,而对于作者,全局权限无法满足需求,仅通过全局权限,要么允许作者编辑不属于自己的文章,要么让作者连自己的文章都无法修改。

上述的应用场景,Django自带的权限机制无法满足需求,需要引入另一种更细的权限机制:对象权限(object permission)

Object Permission是一种对象颗粒度上的权限机制,它允许为每个具体对象授权。仍沿用最开始的例子,如果model B有三个实例 B1,B2 和B3,如果我们把B1的可写权限赋予用户A,则A可以修改B1对象,而对B2,B3无法修改。

对group也一样,如果将B2的可写权限赋予group C,则隶属于group C的所有用户均可以修改B2,但无法修改B1和B3。结合Django自带权限机制和object permission,博客系统中作者的权限控制迎刃而解:系统全局上不允许作者编辑文章,

而对于属于作者的具体文章,赋予编辑权限即可。

Django其实包含了object permission的框架,但没有具体实现,object permission的实现需要借助第三方appdjango-guardian,我们在开发中用调用django guradian封装好的方法即可。

在django权限控制的基础上扩展,自己添加一些业务系统的权限控制。

自己写权限要注意:

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

想对一个功能实现权限控制,要做到只不过在views方法上加一个装饰器在url中添加一条记录就行了,比如:

views

@check_permission
@login_required
def customer_detail(request,customer_id):
customer_obj = models.Customer.objects.get(id=customer_id)
customer_form = forms.CustomerDetailForm(instance=customer_obj) if request.method == 'POST':
customer_form = forms.CustomerDetailForm(request.POST,instance=customer_obj)
if customer_form.is_valid():
customer_form.save()
parent_base_url = '/'.join(request.path.split('/')[:-2])
print("url:",parent_base_url )
return redirect(parent_base_url)
else:
print(customer_form.errors)
return render(request,'crm/customer_detail.html',{'customer_form':customer_form})

urls.py

from django.conf.urls import url,include
from crm import views
urlpatterns = [
url(r'^$',views.dashboard ),
url(r'^customers/$',views.customers,name="customer_list"),
url(r'^customers/(\d+)/$',views.customer_detail,name="customer_detail" ),
]

实现控制:permissions.py

from django.core.urlresolvers import resolve
from django.shortcuts import render
perm_dic = {
# 权限 url别名 请求方式 参数
'view_customer_list': ['customer_list','GET',[]],
'view_customer_info': ['customer_detail','GET',[]],
'edit_own_customer_info': ['customer_detail','POST',['qq','name']],
} def perm_check(*args,**kwargs):
request = args[0]
print(":::",getattr(request,request.method))
print(":::",request.GET)
url_resovle_obj = resolve(request.path_info) #将完整url转换成字符串
current_url_namespace = url_resovle_obj.url_name #获取别名
app_name = url_resovle_obj.app_name #use this name later 获取app name
print(":::::",app_name)
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...") #先判断别名即首先的符合url请求
for perm_key in perm_dic: #循环权限字段
perm_val = perm_dic[perm_key] #权限描述
if len(perm_val) == 3:#otherwise invalid perm data format 必须包含三个字段 url别名,请求方式,请求参数
url_namespace,request_method,request_args = perm_val
print(url_namespace,current_url_namespace)
if url_namespace == current_url_namespace: #matched the url 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 #类似于iptables中默认规则为true,都不匹配的时候放行
return True if matched_flag == True:
#pass permission check
perm_str = "crm.%s" %(matched_perm_key) #crm.view_customer_list
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") #定义装饰器 检测一个完整的动作[url别名+请求方式+请求参数]是否匹配,再检查用户权限
def check_permission(func):
def wrapper(*args,**kwargs):
print('---start check perm---')
if perm_check(*args,**kwargs) is not True:#no permisssion
return render(args[0],'crm/403.html') #没有权限跳珠到403界面
return func(*args,**kwargs) #正常运行
return wrapper

models.py #注册权限进数据库

class UserProfile(models.Model):
user = models.OneToOneField(User) #一对一 类似于外键 添加unique = true
name = models.CharField(max_length=64)
school = models.ForeignKey('School')
def __str__(self): #自定义对象返回可看信息
return self.name
class Meta: #自定义权限控制,只是借用model一个对象操作,并不是在model层面控制。
permissions =(('view_customer_list', u"可以查看客户列表"),
('view_customer_info',u"可以查看客户详情"),
('edit_own_customer_info',u"可以修改自己的客户信息"),
)
===================================================================================
另一种方式
from app01.models import UserProfile
from django.contrib.auth.models import Permission
from django.contrib.contenttypes.models import ContentType content_type = ContentType.objects.get_for_model(UserProfile)
permission = Permission.objects.create(codename='view_customer_list',
                                       name=u"可以查看客户列表",
                                       content_type=content_type) codename   'view_customer_list' 代码逻辑中检查权限时使用
name permissions的描述将permissions打印到屏幕或页面显示
content_type 权限属于那个对象

更多:

https://docs.djangoproject.com/en/1.9/topics/pagination/

  http://www.cnblogs.com/wupeiqi/articles/5237704.html

  http://www.cnblogs.com/alex3714/articles/5535652.html

http://www.jianshu.com/p/01126437e8a4

python 学习笔记十八 django深入学习三 分页,自定义标签,权限机制的更多相关文章

  1. python 学习笔记十九 django深入学习四 cookie,session

    缓存 一个动态网站的基本权衡点就是,它是动态的. 每次用户请求一个页面,Web服务器将进行所有涵盖数据库查询到模版渲染到业务逻辑的请求,用来创建浏览者需要的页面.当程序访问量大时,耗时必然会更加明显, ...

  2. python 学习笔记十六 django深入学习一 路由系统,模板,admin,数据库操作

    django 请求流程图 django 路由系统 在django中我们可以通过定义urls,让不同的url路由到不同的处理函数 from . import views urlpatterns = [ ...

  3. python3.4学习笔记(十八) pycharm 安装使用、注册码、显示行号和字体大小等常用设置

    python3.4学习笔记(十八) pycharm 安装使用.注册码.显示行号和字体大小等常用设置Download JetBrains Python IDE :: PyCharmhttp://www. ...

  4. python 学习笔记十五 django基础

    Python的WEB框架有Django.Tornado.Flask 等多种,Django相较与其他WEB框架其优势为:大而全,框架本身集成了ORM.模型绑定.模板引擎.缓存.Session等诸多功能. ...

  5. (C/C++学习笔记) 十八. 继承和多态

    十八. 继承和多态 ● 继承的概念 继承(inheritance): 以旧类为基础创建新类, 新类包含了旧类的数据成员和成员函数(除了构造函数和析构函数), 并且可以派生类中定义新成员. 形式: cl ...

  6. python cookbook第三版学习笔记十八:可由用户修改的装饰器

    定义一个属性可由用户修改的装饰器: 在前面的介绍中使用装饰器来包装函数,这一章来介绍下如何让用户调整装饰器的属性. 首先来看下代码: from functools import wraps,parti ...

  7. Java基础学习笔记十八 异常处理

    什么是异常?Java代码在运行时期发生的问题就是异常. 在Java中,把异常信息封装成了一个类.当出现了问题时,就会创建异常类对象并抛出异常相关的信息(如异常出现的位置.原因等). 异常的继承体系 在 ...

  8. Python3学习笔记十八

    1.    MTV M:   model     与数据库相关 T:   Template    与html相关 V:   views      与逻辑相关 一.    URL配置 启动:python ...

  9. MYSQL进阶学习笔记十八:MySQL备份和还原!(视频序号:进阶_37)

    知识点十九:MySQL的备份的还原(38) 一.mysql的备份 1.通过使用mysqldump的命令备份 使用mysqldump命令备份,mysqldump命令将数据库中的数据备份成一个文本文件.表 ...

随机推荐

  1. yii2 登录验证

  2. AVAudioPlayer播放本地音频

    AVAudioPlayer苹果官方上说一般用于播放本地音频,不能用于播放网络上的音频. 具体的代码:先导入 #import <AVFoundation/AVFoundation.h> // ...

  3. 无法安装MVC3,错误提示:安装KB2483190(vs10-kb2483190)出错

    原文:无法安装MVC3,错误提示:安装KB2483190(vs10-kb2483190)出错 无法安装MVC3,错误提示:安装KB2483190(vs10-kb2483190)出错. 安装指导:&qu ...

  4. NSMutableRLEArray objectAtIndex:effectiveRange:: Out of bounds

     Bugly:  Trapped uncaught exception 'NSRangeException', reason: 'NSMutableRLEArray objectAtIndex:eff ...

  5. iOS 面试题(三):为什么 weakSelf 需要配合 strong self 使用 --转自唐巧

    问题 继续回答昨天的问题第二问. 我们知道,在使用 block 的时候,为了避免产生循环引用,通常需要使用 weakSelf 与 strongSelf,写下面这样的代码: __weak typeof( ...

  6. varnish 隐藏版本号

    varnish 隐藏方法: 修改default.vcl配置文件. 找到或添加 vcl_deliver 子程序,代码如下: 1 2 3 4 5 sub vcl_deliver {        unse ...

  7. 网页3D引擎“Babylon.JS”入门教程翻译总结

    使用三个月的业余时间把官方教程的入门部分译为中文并上传到github,在下一步编程前做一个总结. 历程: 最早接触游戏编程是在大三下学期,用汇编语言和实验室里的单片机.触摸屏.电机(提供声效)编的打地 ...

  8. 手贱的回忆录 --- L版openrc密码修改(OS_PASSWORD)

    ---恢复内容开始--- 刚刚部署完L版,发现默认登录的管理员账号在41.42.43的openrc文件中,登录名是admin,登录密码却是一串随机码,于是想修改一个简单易记的密码,手贱的把OS_PAS ...

  9. New Concept English 1-10

    Lesson 10 The loss of Titanic The great ship, Titanic, sailed for New York from Southampton on April ...

  10. Your intuition 你的直觉

    If you’re thinking just like everyone else, you aren’t really thinking. Follow your intuition. Do wh ...