python博客开发_python 博客开发之散乱笔记

博客开发之旅:

#回滚,数据存储失败时,还原修改操作

from django.db importtransaction

with transaction.atomic():

do...

...#==========自定义form表单验证----------====#自定义验证规则

defmobile_validate(value):

mobile_re= re.compile(r'^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$')if notmobile_re.match(value):raise ValidationError('手机号码格式错误')#使用自定义验证规则

phone = fields.CharField(validators=[mobile_validate, ],

error_messages={'required': '手机不能为空'},

widget=widgets.TextInput(attrs={'class': "form-control",'placeholder': u'手机号码'}))#多选

course_id =fields.MultipleChoiceField(

choices=models.Course.objects.all().values_list('id','title'),

widget=widgets.SelectMultiple(attrs={'class':'form-control'})

)

View Code

#+============+++++++++++==扩展Django自带的用户认证表=========+++++++++++++===

from django.contrib.auth.models importAbstractUserclassUserInfo(AbstractUser):"""用户信息表"""nid= models.AutoField(primary_key=True)

phone= models.CharField(max_length=11, null=True, unique=True)

avatar= models.FileField(upload_to="avatars/", default="avatars/default.png", verbose_name="头像")

create_time= models.DateTimeField(auto_now_add=True)

blog= models.OneToOneField(to="Blog", to_field="nid", null=True,on_delete=models.CASCADE)def __str__(self):returnself.username#在settings中告诉Django项目用哪张表做认证

AUTH_USER_MODEL = 'app01.UserInfo'

from django.contrib importauth

user= authenticate(username='theuser',password='thepassword')#即验证用户名以及密码是否正确,一般需要username 、password两个关键字参数。#如果认证成功(用户名和密码正确有效),便会返回一个 User 对象。

user= authenticate(username=username, password=password)if user is notNone:

login(request, user)#该函数接受一个HttpRequest对象,以及一个经过认证的User对象。#该函数实现一个用户登录的功能。它本质上会在后端为该用户生成相关session数据。

from django.contrib.auth importlogoutdeflogout_view(request):

logout(request)#该函数接受一个HttpRequest对象,无返回值。#当调用该函数时,当前请求的session信息会全部清除。该用户即使没有登录,使用该函数也不会报错。

if notrequest.user.is_authenticated():pass

#is_authenticated()#用来判断当前请求是否通过了认证。

#auth 给我们提供的一个装饰器工具,用来快捷的给某个视图添加登录校验。

from django.contrib.auth.decorators importlogin_required

@login_requireddefmy_view(request):pass

#若用户没有登录,则会跳转到django默认的 登录URL '/accounts/login/ ' 并传递当前访问url的绝对路径

(登陆成功后,会重定向到该路径)。LOGIN_URL = '/login/' #这里配置成你项目登录页面的路由

#create_user()#auth 提供的一个创建新用户的方法,需要提供必要参数(username、password)等。

from django.contrib.auth.models importUser

user= User.objects.create_user(username='用户名',password='密码',email='邮箱',...)#create_superuser()#auth 提供的一个创建新的超级用户的方法,需要提供必要参数(username、password)等。

from django.contrib.auth.models importUser

user= User.objects.create_superuser(username='用户名',password='密码',email='邮箱',...)#check_password(password)#auth 提供的一个检查密码是否正确的方法,需要提供当前请求用户的密码。密码正确返回True,否则返回False。

ok = user.check_password('密码')#set_password(password)#auth 提供的一个修改密码的方法,接收 要设置的新密码 作为参数。

注意:设置完一定要调用用户对象的save方法!!!

user.set_password(password='')

user.save()

极验: https://docs.geetest.com/install/deploy/server/python

pip install geetest

View Code

# +++++++++++++++++++++++文件上传++++++++++++++++++++

viewsfrom django.views.decorators.csrf importcsrf_exempt

@csrf_exemptdefupload(request):if request.method == 'POST':

file_obj= request.FILES.get('file')

with open('upload/'+file_obj.name,'wb')as f:for i infile_obj.chunks():

f.write(i)return render(request,'upload.html')

html

View Code

#++++++++++++==文档加载完之后才执行 JS 的三种方式===++++++++++++

var a= document.getElementById('username');

alert(a);

};

$(document).ready(function () {

var a= document.getElementById('default_avatar');

alert(a);

});

$(function () {

var a= document.getElementById('default_avatar');

alert(a);

})

View Code

#+++++++++++++++++====头像预览====++++++++++++++++

选择头像

默认头像

#

var fileReader=new FileReader();//读取到当前选中的文件//console.log(this.files[0]);

fileReader.readAsDataURL(this.files[0]);

fileReader.οnlοad=function () {

$('#default_avatar').attr('src',fileReader.result);

}

})

View Code

#-------------Form表单验证在渲染成HTML标签时显示错误信息----------------

{{ obj.username.label }}

{{ obj.username }}{{ obj.errors.username.0 }}
{% for row in obj %}

{{ row.label }}

{{ row }}{{ row.errors.0 }}
{% endfor %}

View Code

# +++++++++++++++++++全局钩子验证密码一致性 以及实时跟新数据+++++++++++++++++++++

classRegForm(Form):

...

re_password=fields.CharField(

min_length=6,

label="确认密码",

widget=widgets.PasswordInput(

attrs={"class": "form-control"},

render_value=True,

),

error_messages={"min_length": "确认密码至少要6位!","required": "确认密码不能为空",

}

)

user_type=fields.ChoiceField(

choices=models.UserType.objects.values_list('id','caption')

)#重写全局的钩子函数,对确认密码做校验

defclean(self):

password= self.cleaned_data.get('password')

re_password= self.cleaned_data.get('re_password')if re_password and password !=re_password:

self.add_error('re_password',ValidationError('两次密码不一致!'))else:return self.cleaned_data #注意返回

#在使用选择标签时,需要注意choices的选项可以从数据库中获取,但是由于是静态字段

#***获取的值无法实时更新***,那么需要自定义构造方法从而达到此目的。

def __init__(self, *args, **kwargs):

super(RegForm,self).__init__(*args, **kwargs)

self.fields['user_type'].choices = models.UserType.objects.values_list('id','caption')

View Code

# ++++==+++__++===-+_+_===# 自己生成验证码图片 # ++++==+++__++===-+_+_===#

from PIL importImage, ImageDraw, ImageFont

img_obj= Image.new('RGB',(220,40),random_color()) #图片对象

draw_obj = ImageDraw.Draw(img_obj) #画笔对象

font_obj = ImageFont.truetype('static/fonts/kumo.ttf', 40) #字体对象

char_list = random_char() #验证码字符串

request.session["code_img"] = "".join(char_list) #将字符串保存到session会话

for i in range(len(char_list)): #将字符画到图片上

draw_obj.text((10+50*i,0),char_list[i],fill=random_color(),font=font_obj)#draw_obj.line((begin,end),fill=random_color(),width=random.randint(1,4)) # 画线条#draw_obj.point(width, height, fill=random_color()) # 画点

draw_obj.arc((x, y, x+z, y+z), 0, 360, fill=random_color()) #画弧线 圆

from io importBytesIO

io_obj= BytesIO() #将生成的图片数据保存在io对象中

img_obj.save(io_obj, "png") #从io对象里面取上一步保存的数据

data =io_obj.getvalue()returnHttpResponse(data)++++

验证码加载失败$('#get_code').click(function () {//点击图片刷新验证码

$(this)[0].src+= "?";

});++++

View Code

#+==================# 重写局部钩子函数,对用户名做校验和ajax实时检验===========================+

classRegForm(Form):

username=fields.CharField(

max_length=16,

label="用户名",

error_messages={"max_length": "用户名最长16位","required": "用户名不能为空",

},

widget=widgets.TextInput(

attrs={"class": "form-control"},

)

)defclean_username(self):

username= self.cleaned_data.get('username')

is_exist= models.UserInfo.objects.filter(username=username)ifis_exist:

self.add_error('username',ValidationError('用户名已存在'))else: #重写的是局部钩子,所以返回检验的字段

returnusername#username输入框失去焦点,使用ajax检验用户名是否存在

@csrf_exemptdefcheck_username_exist(request):

ret= {'status':False,'msg':None}

is_exist= models.UserInfo.objects.filter(username=request.POST.get('username'))ifis_exist:

ret['status']=True

ret['msg']='用户名已存在'

returnHttpResponse(json.dumps(ret))returnHttpResponse(json.dumps(ret))#

#取消浏览器自动匹配#$('#id_username').on('input',function () { # 内容变动就提交

$('#id_username').blur(function () {

$.ajax({

url:'/check_username_exist/',

data: {'username': $(this).val()},

method:'post',

dataType:'json',

success: function (data) {if(data.status) {

$('#id_username').next().text(data.msg);

console.log(data.msg);

}

}

})

})#Django admin 使用#在app/admin.py文件中注册表

from django.contrib importadminfrom app01 importmodels

admin.site.register(models.UserInfo)

admin.site.register(models.Blog)#在settings配置显示中文

LANGUAGE_CODE = 'zh-hans'

classUserInfo():

...classMeta:

verbose_name= '用户' #给表起名

verbose_name_plural = verbose_name #显示复数也用'用户'来显示

在admin后台中显示中文表名

View Code

#=========== # Django用户上传的都叫media文件==================#setting.py#media配置,用户上传的文件都默认放在这个文件夹下

MEDIA_ROOT = os.path.join(BASE_DIR,"media")

MEDIA_URL= "/media/"

#urls.py

from django.views.static importservefrom django.conf importsettings

re_path('media/(?P.*)$',serve,{"document_root":settings.MEDIA_ROOT}),#做了media配置,用户上传文件都会在media/xx中。

View Code

#_+_+_+_+_+_+_+_+_+_+_+导入Django,单独测试某个功能_+_+_+_+_+_+_+_+_+_+_+_+_+

test.pyimportosif __name__ == '__main__':

os.environ.setdefault('DJANGO_SETTINGS_MODULE', '博客.settings')importdjango

django.setup()from app01 importmodels

obj=models.UserInfo.objects.all()print(obj.query)

View Code

# -=======----博客文章-=======----

{{ article.title }}

...

{{ article.desc }}

分组和聚合 https://www.cnblogs.com/liwenzhou/p/8660826.html1. 分组

ORM中values或者values_list 里面写什么字段,就相当于select 什么字段

ret= models.Employee.objects.all().values("dept", "age")

相当于:

SELECT `employee`.`dept`, `employee`.`age` FROM `employee` LIMIT21; args=()2. ORM中 annotate 前面是什么就按照什么分组!from django.db.models importAvg

ret= models.Employee.objects.values("province").annotate(a=Avg("salary")).values("province", "a")

相当于:

SELECT `employee`.`province`, AVG(`employee`.`salary`) AS `a` FROM `employee` GROUP BY `employee`.`province` ORDER BY NULL LIMIT21; args=()3. extra -->在执行ORM查询的时候执行额外的SQL语句#查询person表,判断每个人的工资是否大于2000

ret =models.Person.objects.all().extra(

select={"gt": "salary > 2000"}

)

相当于:

SELECT (salary> 2000) AS `gt`, `person`.`id`, `person`.`name`, `person`.`salary`, `person`.`dept_id` FROM `person` LIMIT 21; args=()4. 直接执行原生的SQL语句,类似pymysql的用法from django.db importconnection

cursor= connection.cursor() #获取光标,等待执行SQL语句

cursor.execute("""SELECT * from person where id = %s""", [1])

row=cursor.fetchone()print(row)#=====++++++创建数据库表,插入时间++++++=======

mysql>create table test(d date, dt datetime, t time);

mysql>insert into test(d,dt,t) values(now(),now(),now());

mysql>select date_format(dt,'%Y-%m') from test; #格式化,只看年月

View Code

#=++++++++++++==========+++++母板,子板,自定义templates+++====+++++++++++===========

母板

{{ blog.title }}
{{ blog.title }}
{% load my_tags %}#在这使用自定义templates

{% get_left_menu username %}

{% block page-main %}

{% endblock %}

子板

{% extends 'base.html' %}

{% block page-main %}

{% for article in article_list %}

。。。。。。。

{% endfor %}

{% endblock %}

自定义templates

在app下新建目录templatetags,在新建目录下新建文件my_tags.pyfrom django importtemplatefrom app01 importmodelsfrom django.db.models importCount

register= template.Library() #固定写法

@register.inclusion_tag("left_menu.html")defget_left_menu(username):

user= models.UserInfo.objects.filter(username=username).first()

blog=user.blog#查询文章分类及对应的文章数

category_list = models.Category.objects.filter(blog=blog)#查文章标签及对应的文章数

tag_list = models.Tag.objects.filter(blog=blog).annotate(c=Count("article")).values("title", "c")#按日期归档

#archive_list = models.Article.objects.filter(user=user).extra(

#select={"archive_ym": "date_format(create_time,'%%Y-%%m')"}

#).values("archive_ym").annotate(c=Count("nid")).values("archive_ym", "c")

return{"category_list":category_list,"tag_list": tag_list,

}

创建left_menu.html

文章分类
{% for category in category_list %}

{{ category.title }}({{ category.article_set.all.count }})

{% endfor %}
标签分类
{% for tag in tag_list %}

{{ tag.title }}({{ tag.c }})

{% endfor %}

View Code

# ===========-----====-----====-------点赞 js-------======-----======-----=============

defdianzan_up_down(request):

ret= {'status':False,'msg':None}

article_id= request.POST.get('article_id')

is_up= json.loads(request.POST.get('is_up'))

user=request.userifuser:try:

models.ArticleUpDown.objects.create(user=user,article_id=article_id,is_up=is_up)

models.Article.objects.filter(nid=article_id).update(up_count=F('up_count')+1)

ret['status'] =True

ret['is_up'] =is_upreturnHttpResponse(json.dumps(ret))exceptException as e:

is_up= models.ArticleUpDown.objects.filter(user=user,article_id=article_id).first().is_up

ret['first_action']=is_upreturnHttpResponse(json.dumps(ret))

ret['msg'] = '请先登录'

returnHttpResponse(json.dumps(ret))

{{ article.up_count }}

{{ article.down_count }}

{% csrf_token %}#可以将文章id渲染出来

$('#div_digg .action').click(function () {

var is_up= $(this).hasClass('diggit');

var crticle_id= "{{ article.pk }}";#var article_id = $('.info').attr('article_id');当JS保存为静态文件时,获取文章id

$.ajax({

url:'/blog/article/up_down/',

type:'post',

data: {'article_id': crticle_id,'is_up': is_up,'csrfmiddlewaretoken': $('[name=csrfmiddlewaretoken]').val()

},

dataType:'json',

success: function (data) {if(data.status) {if(data.is_up) {

var count= $('#digg_count').text();

count= parseInt(count) + 1;

$('#digg_count').text(count);

}else{

var count= $('#bury_count').text();

count= parseInt(count) + 1;

$('#digg_count').text(count);

}

}else{if(data.msg) {

$('#digg_tips').text(data.msg);

}else{if(data.first_action) {

$('#digg_tips').text('您已经推荐过啦');

}else{

$('#digg_tips').text('您已经反对过啦');

}

}

setTimeout(function () {

$("#digg_tips").html("")

},1000)

}

}

})

})

#========= 响应ajax,数据直接使用,不用写dataType:'json' =========

from django.http importJsonResponsereturn JsonResponse({'',''})

View Code

# +++++++++++++++++++使用JS动态绑定事件+++++++++++++++++++++++

//後面添加的元素無法綁定事件,需預加載

$(document).on('click','#reply',function () {

$("#comment_content").focus();

var v= "@" + $(this).attr("username") + "\n";

$("#comment_content").val(v);

pid= $(this).attr("comment_id")

});

View Code

#_+__________++++++++评论树例子+__________+++++++++

from django.http importJsonResponsedefcomment_tree(request,article_id):

comment_list= list(models.Comment.objects.filter(article_id=article_id).values("pk","content","parent_comment_id","create_time",'user__username'))print(comment_list) #将 转为列表。若直接json.dumps(comment_list)会报错!

return JsonResponse(comment_list,safe=False)#静态文件中(外部js文件)需要使用的值,最好在渲染的时候将值作为属性存到标签中。方便取值。

$(function () {//获取评论列表

$.ajax({

url:'/blog/comment/' + '{{ article.pk }}/',// dataType:'json',// returnHttpResponse(json.dumps(dict(enumerate(comment_list))))// enumerate(comment_list,start=1)指定起始值,那么下面的.each index就不用加值了,不过这个麻烦// 瞎折腾得是,以上3行 等价 return JsonResponse(comment_list,safe=False)

success: function (data) {

$.each(data, function (index, comment_dict) {

index= index + 1;

var s= '

\n' +

'

\n' +

'#' + index + '楼\n' +

'' + comment_dict.create_time + '\n' +

' \n' +

'

回复\n' +

'

\n' +

'

' + comment_dict.content + '
\n' +

'

';if(comment_dict.parent_comment_id) {//子评论 追加到父评论下

var pid=comment_dict.parent_comment_id;

$('[comment_id="' + pid + '"]').append(s);

}else{//根评论

$('.comment_tree').append(s);

}

})

}

});

pid= ""; //有值即回复别人的评论内容,无值评论文章//子评论设置pid

$(document).on('click', '#reply', function () {

var v= "@" + $(this).attr("username") + "\n";

$("#comment_content").focus().val(v);

pid= $(this).attr("comment_pk");

});//提交评论

$('#comment_btn').click(function () {

var content= $('#comment_content').val();

var article_id= $('#info').attr('article_id');

$.ajax({

url:'/blog/comment/',

type:'post',

data: {'content': content, 'article_id': article_id, 'pid': pid,

csrfmiddlewaretoken: $("[name='csrfmiddlewaretoken']").val(),

},

success: function (data) {

var s= '

' + content + '
';//生成tag,添加到页面暂不刷新,清除文本框,将pid清空,避免影响提交数据。

$('.comment_tree').append(s);

$('#comment_content').val('');

pid= "";

}

})

})

})

View Code

# ===========================富文本编辑器=kindeditor===============================

window.editor= K.create('#article_content', {

width:'800px',

uploadJson:"/upload/", //上传图片什么的需要填参数

extraFileUploadParams: {"csrfmiddlewaretoken": $("[name='csrfmiddlewaretoken']").val()

},

filePostName:"upload_file",//request.FILE.get('') 文件键名

});

});上传图片defupload(request):if request.method == 'POST':

file_obj= request.FILES.get('upload_file')

path= 'media/add_article/'+file_obj.name

with open(path,'wb')as f:for i infile_obj.chunks():

f.write(i)

res={'error':0, #没有出错

'url':path,

}returnHttpResponse(json.dumps(res))return HttpResponse('')

提交文章#使用beautifulSoup过滤文章中的JS代码,防止XSS攻击

defadd_article(request):if request.method=="POST":

title=request.POST.get('title')

article_content=request.POST.get('article_content')

user=request.userfrom bs4 importBeautifulSoup

bs= BeautifulSoup(article_content,'html.parser')#过滤非法字符

for tag inbs.find_all():#print(tag.name)

if tag.name in ['script','link']:

tag.decompose()

desc= bs.text[0:150]+'...'article_obj= models.Article.objects.create(user=user,title=title,desc=desc)

models.ArticleDetail.objects.create(content=str(bs),article=article_obj)return redirect('/blog/%s/'%request.user.username)return render(request,'add_article.html')#orm查询,基于对象查询(子查询),反向查询按表名小写_set.all()#基于queryset和__查询(join查询)正向查询:按字段 反向查询:表名小写#select publish.email from Book#left join Publish on book.publish_id=publish.nid#where book.title="python"#按逻辑来,对象查询是基于单个对象!?,join只要连上表就能拿值!。

View Code

# ———————————————————————————————————简单使用admin—————————————————————————————————————

from django.utils.safestring importmark_safefrom app01 importmodelsclassUserInfoConfig(admin.ModelAdmin):defdeletes(self):return mark_safe("删除")

list_display= ["username","email","create_time",'blog',deletes]#在admin管理页面,显示出用户表的用户信息字段,deletes是自定义的跳转链接

list_display_links= ["email"]#设置哪个字段可以点击跳转到编辑当前页信息的页面

list_filter=["username","email","create_time",'blog']#筛选功能,按字段条件筛选,指定多个字段组合筛选。

list_editable=["username",'blog']#此配置需要有list_display_links = ["email"]配置才能生效,即在当前页编辑其他字段信息,效果和直接在被编辑字段的编辑页面相同

search_fields=["username","email"]#添加搜索功能,以列表中的字段过滤出的信息后进行查找

defpatch_init(self,request,queryset):

queryset.update(price=100)

patch_init.short_description= "批量初始化"actions=[patch_init,]#添加一个批量操作选项。传入执行方法名

change_list_template="login.html"

#自己的后台管理页面。

View Code

# -------------------Xadmin----------------------

流程1、启动

在settings文件中配置上'Xadmin.apps.XadminConfig',

将会自动执行ready方法,查找所有app中的Xadmin模块

autodiscover_modules('Xadmin')2、注册

单例模式from Xadmin.service.Xadmin importsitefrom app01 importmodels

site.registry(models.Test)3、设计url

为每个app下的model设计增删改查url127.0.0.1:8008/admin/app01/book/1/change/ :改id=1的数据#url的路由分发

path('test/',([re_path('\d+',func),re_path('(\d+)',([],None,None)),],None,None))#url

path('xadmin/', Xadmin.site.urls),#Xadmin组件 -> apps.py

from django.apps importAppConfigfrom django.utils.module_loading importautodiscover_modulesclassXadminConfig(AppConfig):

name= 'Xadmin'

defready(self):

autodiscover_modules('Xadmin')#Xadmin -> service -> Xadmin.py

from django.urls importpath,re_pathfrom django.shortcuts importrender,HttpResponse,redirectclassModelXadmin(object):def __init__(self,model,site):

self.model=model

self.site=sitedeflist_view(self,request):return HttpResponse('list_view')defadd_view(self,request):return HttpResponse('add_view')defchange_view(self,request,id):return HttpResponse('change_view')defdelete_view(self,request,id):return HttpResponse('delete_view')defget_urls2(self):

temp=[]

temp.append(re_path('^$',self.list_view))

temp.append(re_path('^add/$',self.add_view))

temp.append(re_path('^(\d+)/change/$',self.change_view))

temp.append(re_path('^(\d+)/delete/$',self.delete_view))returntemp

@propertydefurls2(self):#路由,某个表的增删改查url

returnself.get_urls2(),None,NoneclassXadminSite(object):def __init__(self,name='admin'):

self._registry={}defget_urls(self):

temp=[]for model,xadmin_class_obj inself._registry.items():

app_name=model._meta.app_label

model_name=model._meta.model_name

temp.append(re_path('^%s/%s/'%(app_name,model_name),xadmin_class_obj.urls2))returntemp

@propertydefurls(self):#路由,app下的某个表url

returnself.get_urls(),None,Nonedef registry(self,model,xadmin_class=None,**kwargs):if notxadmin_class:

xadmin_class=ModelXadmin

self._registry[model]=xadmin_class(model,self)

site=XadminSite()#app01 -> Xadmin.py

from Xadmin.service.Xadmin importsitefrom app01 importmodels

site.registry(models.Test)

笔记暂断

View Code

# =-=-=-=-=-=-=-=-=rbac基于角色的访问权限控制,大致流程=--==-=-=-=-=-=-=-

#rbac -> views.py

from django.shortcuts importrender,redirectfrom rbac.models import *

defrbac_list(request):'''用户权限信息'''role_list=Role.objects.all()

user= Role.objects.values('o2o_user__user_id','o2o_user__user__username')

user_list=[]for item inuser:if item['o2o_user__user_id']:

user_list.append((item['o2o_user__user_id'],item['o2o_user__user__username']))

obj=roleForm()return render(request,'rbac.html',{'role_list':role_list,'user_list':user_list,'obj':obj})from django.forms importForm,fields,widgetsclassroleForm(Form):

users=fields.ChoiceField(

choices=O2o_User.objects.values_list('user__nid','user__username')

)

roles=fields.MultipleChoiceField(

choices=Role.objects.values_list('pk','title')

)defrbac_edit(request):'''修改权限'''id= request.POST.get('users')

roles= request.POST.getlist('roles')

obj= roleForm({'users':id,'roles':roles})

res=obj.is_valid()ifres:

obj= O2o_User.objects.filter(user_id=id).first()

obj.roles.set(roles)return redirect('/rbac/')#中间件过滤请求

importrefrom django.utils.deprecation importMiddlewareMixinfrom django.shortcuts importHttpResponse,redirectclassValidPermission(MiddlewareMixin):defprocess_request(self,request):

current_path=request.path_info

pass_url= ["/index/",'/info/','/register/.*','/login/.*','/logout/','/admin/.*',]#白名单直接放行

for rule inpass_url:

ret=re.match(rule, current_path)ifret:returnNone#不在白名单内,判断是否登录用户。

if notrequest.user.username:return redirect('/login/')

permission_dict= request.session.get('permission_dict')for item inpermission_dict.values():

urls= item['url']for rule inurls:

rule= '^%s$'%rule

ret=re.match(rule,current_path)ifret:#注入权限,用于控制template模板显示增删改

request.action = item['action']returnNoneprint('没有权限%s'%current_path)return HttpResponse('没有权限%s'%current_path)#rbac -> permission.py

from rbac importmodelsdefvalid_permission(request):'''提取用户权限并存储到session'''

#print('ssssssssssssssss',request.path_info,user.email)

res = models.O2o_User.objects.filter(user=request.user).values('roles__permissions__url',#'roles__permissions__title',

'roles__permissions__action','roles__permissions__group_id',)

per={}for item inres:if item['roles__permissions__group_id'] inper:

per[item['roles__permissions__group_id']]['url'].append(item['roles__permissions__url'])#per[item['roles__permissions__group_id']]['title'].append(item['roles__permissions__title'])

per[item['roles__permissions__group_id']]['action'].append(item['roles__permissions__action'])else:

per[item['roles__permissions__group_id']] ={'url':[item['roles__permissions__url'],],#'title':[item['roles__permissions__title'],],

'action':[item['roles__permissions__action'],]

}

request.session['permission_dict'] =perprint(per)#使用auth认证,登录成功就将用户权限保存到session中

auth.login(request,user)

valid_permission(request)#在rbac中创建一个模板用于rbac权限设置,用户权限不满足就只渲染部分功能。

View Code

# -===-=-=-=-=-=-=-=-=-=-=-=-=-返回顶部=-=-=-=-=-=-=-=-

var $height=$(window).scrollTop();if ($height > 200) {

$('#back_top').removeClass('hidden');

}else{

$('#back_top').addClass('hidden');

}

})

$('#back_top').click(function () {

$('body,html').animate({

scrollTop: 0

},1000);

})

View Code

# -=-=-=-=-=-=-=-ajax请求后端返回对象,前端直接使用

comment_list = list(models.Comment.objects.filter(article_id=article_id).values("pk","content"))return JsonResponse(comment_list, safe=False) 传送对象

success: function (data) {

$.each(data, function (index, comment_dict) {

comment_dict.pk

}}

View Code

#-=-=-=-==========页面跳转=-=-=-=-=-=-=-=-=-

//以下方式直接跳转

window.location.href='hello.html';//以下方式定时跳转

setTimeout("javascript:location.href='hello.html'", 5000);

#结合了倒数的javascript实现

setInterval("redirect()", 1000);

function redirect()

{

document.getElementById('totalSecond').textContent = --second;if (second < 0) location.href = 'hello.html';

}

View Code

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值