django之博客系统个人资料,django之博客系统毕业设计论
项目流程:1、搞清楚需求基于用户认证组件作家(作者的简写)和埃阿斯实现登录验证(图片验证码)基于形式组件和埃阿斯实现注册功能设计博客系统首页(文章列表渲染)设计个人站点页面文章详情页实现文章点赞功能实现文章的评论文章的评论评论的子评论富文本编辑框以及跨站脚本攻击2、设计表结构
从django.contrib.auth.models导入用户,抽象用户
类UserInfo(AbstractUser):
用户信息
nid=模型AutoField(primary_key=True)
电话=型号CharField(max_length=11,null=True,unique=True)
头像=模特. FileField(upload_to=avatars/,default=/avatars/default.png )
创建时间=模型。日期时间字段(详细名称=创建时间,auto_now_add=True)
博客=模特OneToOneField(to=Blog ,to_field=nid ,null=True,on_delete=models .级联)
def __str__(self):
返回自我。用户名
班级博客(模特。型号):
博客信息表(站点表)
nid=模型AutoField(primary_key=True)
标题=模型CharField(verbose_name=个人博客标题最大长度=64)
站点名称=模型CharField(verbose_name=站点名称最大长度=64)
主题=模型CharField(verbose_name=博客主题,max_length=32)
def __str__(self):
返回自我标题
类别类别(型号。型号):
博主个人文章分类表
nid=模型AutoField(primary_key=True)
标题=模型CharField(verbose_name=分类标题,max_length=32)
博客=模特ForeignKey(详细名称=所属博客,to=博客,to_field=nid ,on _ delete=模型。级联)
def __str__(self):
返回自我标题
类别标签(型号。型号):
nid=模型AutoField(primary_key=True)
标题=模型CharField(verbose_name=标签名称,max_length=32)
博客=模特ForeignKey(详细名称=所属博客,to=博客,to_field=nid ,on _ delete=模型。级联)
def __str__(self):
返回自我标题
类文章(模型。型号):
nid=模型AutoField(primary_key=True)
标题=模型CharField(max_length=50,verbose_name=文章标题)
desc=模特CharField(max_length=255,verbose_name=文章描述)
创建时间=模型。日期时间字段(详细名称=创建时间,auto_now_add=True)
内容=模型。文本字段()
comment_count=models .整数域(默认值=0)
up _ count=型号。整数域(默认值=0)
向下计数=型号。整数域(默认值=0)
用户=模型ForeignKey(详细名称=作者,to=UserInfo ,to_field=nid ,on_delete=models .级联)
类别=型号ForeignKey(to=Category ,to_field=nid ,null=True,on_delete=models .级联)
标签=模型ManyToManyField(
to=Tag ,
通过=第二条标签,
through _ field=(文章,标签),
)
def __str__(self):
返回自我标题
第2类标签(型号。型号):
nid=模型AutoField(primary_key=True)
文章=模特ForeignKey(详细名称=文章,to=Article ,to_field=nid ,on_delete=models .级联)
标签=模型ForeignKey(详细名称=标签,to=Tag ,to_field=nid ,on_delete=models .级联)
类别元:
unique_together=[
(文章,标签),
]
def __str__(self):
v=自我。文章。标题-自我。标签。标题
返回v
类文章下载(模型。型号):
点赞表
nid=模型AutoField(primary_key=True)
用户=模型ForeignKey(UserInfo ,null=True,on_delete=models .级联)
文章=模特ForeignKey(Article ,null=True,on_delete=models .级联)
is_up=型号BooleanField(默认值=真)
类别元:
unique_together=[
(文章,用户),
]
班级评论(模特。型号):
评论表
nid=模型AutoField(primary_key=True)
用户=模型ForeignKey(详细名称=评论者,to=UserInfo ,to_field=nid ,on_delete=models .级联)
文章=模特ForeignKey(详细名称=评论文章,to=Article ,to_field=nid ,on_delete=models .级联)
创建时间=模型。日期时间字段(详细名称=创建时间,auto_now_add=True)
内容=模型CharField(verbose_name=评论内容最大长度=255)
parent _ comment=模型.ForeignKey(self ,null=True,on_delete=models .级联)
def __str__(self):
返回自我内容
根评论:对文章的评论
子评论:对评论的评论
111
444
555
222
333
评论
NID user _ id article _ id content parent _ comment _ id(null=True)
1 1 1 1111空
2 2 1 222空
3 3 1 333空
4 4 1 444 1
5 5 1 555 4型号。巴拉圭
3、按照每一个功能分别进行开发Myforms.py
# -*-编码:utf-8 -*-
#作者:于超
#数据:2018/7/12 09:19
从框架进口表格
从django.forms导入小部件
从博客.模型导入用户信息
从异常导入非字段错误,验证错误
部件数量属性是框架对超文本标记语言输入元素的表示,负责渲染超文本标记语言和提取获取/发布的字典数据
类用户表单(表单。表单):
用户=表单CharField(max_length=32,
error_messages={required :该字段不能为空},
标签=用户名,
# 渲染后,小部件将设置属性attrs={class: form-control}
小部件=小部件TextInput(attrs={ class : form-control },)
)
pwd=表格。夏菲尔德(
max_length=32,
标签=密码,
小部件=小部件密码输入(attrs={ class : form-control },))
re_pwd=表单CharField(max_length=32,
标签=确认密码,
小部件=小部件密码输入(attrs={ class : form-control },))
电子邮件=表单EmailField(max_length=32,
标签=邮箱,
小部件=小部件邮件输入(attrs={ class : form-control },))
定义清理_用户(自己):
# clean_data是提交成功后的字典数据
val=self。已清理_数据。get(用户)
用户=用户信息。对象。过滤器(用户名=val).首先()
如果不是用户:
返回值
否则:
引发验证错误(该用户已注册) # 描述错误的信息
定义清理(自我):
pwd=self.cleaned_data.get(pwd )
re _ pwd=self。已清理_数据。get( re _ pwd )
# 判断两次密码都存在,且密码确认正常,返回数据
如果pwd和回复密码:
如果密码==密码:
返回自我清理_数据
否则:
引发验证错误(两次密码不一致) # 可以传入元祖数据,定义错误信息,错误代码,传递给错误信息的参数
否则:
返回自我清理_数据自定义形式
models.py
从django.db导入模型
从django.contrib.auth.models导入抽象用户
#详细名称给类模型,起一个可读的名字
类UserInfo(AbstractUser):
用户信息
nid=模型AutoField(primary_key=True)
电话=型号CharField(max_length=11,null=True,unique=True) #电话
头像=模特. FileField(upload_to=avatars/,default= avatars/default。png )#默认头像
# 创建时间,自动_立即_添加作用是无法修改时间
创建时间=模型。日期时间字段(详细名称=创建时间,auto_now_add=True)
博客=模特OneToOneField(to=Blog ,to_field=nid ,null=True,on_delete=models .级联)
#用户信息对象的返回结果,以用户名显示
def __str__(self):
返回自我。用户名
# 用户和博客,一对一
班级博客(模特。型号):
博客信息
nid=模型AutoField(primary_key=True)
标题=模型CharField(verbose_name=个人博客标题最大长度=64)
站点名称=模型CharField(verbose_name=站点名称最大长度=64)
主题=模型CharField(verbose_name=博客主题,max_length=32)
def __str__(self):
返回自我标题
# 博客分类
类别类别(型号。型号):
博主个人文章分类表
nid=模型AutoField(primary_key=True)
标题=模型CharField(verbose_name=分类标题,max_length=32)
#关联博客表,一个博客可以有多个分类
博客=模特ForeignKey(详细名称=所属博客,to=博客,to_field=nid ,on _ delete=模型。级联)
def __str__(self):
返回自我标题
# 标签分类
# 一个博客对应多个标签
类别标签(型号。型号):
nid=模型AutoField(primary_key=True)
标题=模型CharField(verbose_name=标签名称,max_length=32)
博客=模特ForeignKey(详细名称=所属博客,to=博客,to_field=nid ,on _ delete=模型。级联)
#标签对象返回标签名字
def __str__(self):
返回自我标题
# 文章
类文章(模型。型号):
nid=模型AutoField(primary_key=True)
标题=模型CharField(max_length=50,verbose_name=文章标题)
desc=模特CharField(max_length=255,verbose_name=文章描述)
创建时间=模型。日期时间字段(详细名称=创建时间,auto_now_add=True)
内容=模型TextField() #文章内容
comment_count=models .IntegerField(默认值=0) #评论数
up_count=型号IntegerField(默认值=0) #点赞数
向下计数=型号IntegerField(默认值=0) #点踩数
# 一对多,一个作者可以有多个文章,外键放在多的表里
用户=模型ForeignKey(详细名称=作者,to=UserInfo ,to_field=nid ,on_delete=models .级联)
# 一对多,一个分类可以有多个文章,
类别=型号ForeignKey(to=Category ,to_field=nid ,null=True,on_delete=models .级联)
# 一个文章可以有多个标签,一个标签可以有多个文章,多对多
多对多字段字段会自动生成第三张表
使用穿过参数,找到自己编写的类,创建第三张表模型,方便扩展字段
标签=模型ManyToManyField(
to=Tag ,
通过=第二条标签,
through _ field=(文章,标签),
)
def __str__(self):
返回自我标题
# 文章多对多关联标签表
第2类标签(型号。型号):
nid=模型AutoField(primary_key=True)
文章=模特ForeignKey(详细名称=文章,to=Article ,to_field=nid ,on_delete=models .级联)
标签=模型ForeignKey(详细名称=标签,to=Tag ,to_field=nid ,on_delete=models .级联)
类别元:
unique_together=[
(文章,标签),
]
def __str__(self):
v=自我。文章。标题-自我。标签。标题
返回v
类文章下载(模型。型号):
点赞表
哪个用户对哪张表,进行点赞,还是踩灭
nid=模型AutoField(primary_key=True)
# 哪个用户操作的,关联用户表
用户=模型ForeignKey(UserInfo ,null=True,on_delete=models .级联)
# 对哪个文章操作的,关联文章表
文章=模特ForeignKey(Article ,null=True,on_delete=models .级联)
is_up=型号BooleanField(默认值=真)
类别元:
# 通过两个字段保持唯一性,文章和用户的组合必须唯一
unique_together=[
(文章,用户),
]
# 评论
班级评论(模特。型号):
评论表
nid=模型AutoField(primary_key=True)
# 关联用户表,一个用户可以有多条评论
用户=模型ForeignKey(详细名称=评论者,to=UserInfo ,to_field=nid ,on_delete=models .级联)
# 关联文章表,一个文章能有多个文章
文章=模特ForeignKey(详细名称=评论文章,to=Article ,to_field=nid ,on_delete=models .级联)
创建时间=模型。日期时间字段(详细名称=创建时间,auto_now_add=True)
# 内容
内容=模型CharField(verbose_name=评论内容最大长度=255)
# 父评论,自关联写法,关联评论,可以写自己
parent_comment=模型.ForeignKey(self ,null=True,on_delete=models .级联)
def __str__(self):
返回自我内容
根评论:对文章的评论
子评论:对评论的评论
-
如此结构,无法存储子评论
评论表
突边用户标识文章标识创建时间内容这里应该有个家长_评论父评论(自关联)
1 1 1 xx 11111
2 2 1 xx 2222
3 3 1 xx 33333
自定义models.py
settings.py
项目的姜戈设置。
由" django-管理startproject "使用姜戈2.0.1生成。
有关此文件的更多信息,请参见
https://docs.djangoproject.com/en/2.0/topics/settings/
有关设置及其值的完整列表,请参见
https://docs.djangoproject.com/en/2.0/ref/settings/
导入操作系统
#像这样在项目内部构建路径:os.path.join(BASE_DIR,)
BASE _ DIR=OS。路径。dirname(OS。路径。dirname(OS。路径。ABS路径(_ _ file _ _))
#快速启动开发设置-不适合生产
#请参阅https://份文件。django项目。com/en/2.0/how to/deployment/check list/
#安全警告:生产中使用的密钥要保密!
SECRET _ KEY= ECL VH _ I(m99c *)$)j $ 5 pgpjhuv!4lc#z9t3j00d)x3c *js)x
#安全警告:不要在生产中打开调试的情况下运行!
调试=真
ALLOWED_HOSTS=[]
#应用程序定义
INSTALLED_APPS=[
django.contrib.admin ,
django.contrib.auth ,
django.contrib.contenttypes ,
django.contrib.sessions ,
django.contrib.messages ,
django.contrib.staticfiles ,
"博客",
]
中间件=[
姜戈。中间件。安全。安全中间件,
姜戈。贡献。会话。中间件。会话中间件,
姜戈。中间件。常见。通用中间件,
姜戈。中间件。csrf。 csrfviewmiddleware ,
姜戈。贡献。auth。中间件。认证中间件,
姜戈。贡献。消息。中间件。消息中间件,
姜戈。中间件。点击顶举。xframeoptions中间件,
]
ROOT_URLCONF=。 URL
模板=[
{
后端姜戈。模板。后端。姜戈。django模板,
DIRS: [os.path.join(BASE_DIR, templates)]
,
APP_DIRS :对,
选项:{
上下文处理者:[
姜戈。模板。上下文处理器。调试,
姜戈。模板。上下文处理器。请求,
姜戈。贡献。auth。上下文处理器。授权,
姜戈。贡献。消息。上下文处理器。消息,
],
},
},
]
WSGI _ APPLICATION=。WSGI。应用程序
#数据库
# https://docs.djangoproject.com/en/2.0/ref/settings/#databases
数据库数量={
# 默认:{
# 引擎: django.db.backends.sqlite3 ,
# NAME: os.path.join(BASE_DIR, db.sqlite3 ),
# }
# }
数据库={
默认:{
引擎: django.db.backends.mysql ,
名称:,#要连接的数据库,连接前需要创建好
用户:根,#连接数据库的用户名
密码":",#连接数据库的密码
主机: 127.0.0.1 ,#连接主机,默认本级
端口:3306 #端口默认3306
}
}
#密码验证
# https://个文档。django项目。com/en/2.0/ref/settings/#验证密码验证器
AUTH _ PASSWORD _ validator=[
{
名字:姜戈。贡献。auth。密码验证.用户属性相似性验证器,
},
{
名字:姜戈。贡献。auth。密码验证.MinimumLengthValidator ,
},
{
名字:姜戈。贡献。auth。密码验证.CommonPasswordValidator ,
},
{
名字:姜戈。贡献。auth。密码验证.NumericPasswordValidator ,
},
]
这里不写这个,
模板继承抽象用户报错:
授权.用户组:(字段E304)
AUTH_USER_MODEL=blog .用户信息
#国际化
# https://docs.djangoproject.com/en/2.0/topics/i18n/
语言代码=en-us
TIME_ZONE=亚洲/上海
USE_I18N=True
USE_L10N=True
USE_TZ=False
#静态文件(CSS、JavaScript、图像)
# https://docs.djangoproject.com/en/2.0/howto/static-files/
STATIC_URL=/static/
STATICFILES_DIRS=[
os.path.join(BASE_DIR, static ),
]
# 与用户上传相关的配置
MEDIA _ ROOT=OS。路径。加入(BASE _ DIR, MEDIA )
MEDIA_URL=/media/
日志记录={
版本:1,
disable _ existing _ loggers :False,
处理程序:{
控制台:{
级别:调试,
类":"日志记录 StreamHandler ,
},
},
"记录器":{
django.db.backends :
处理程序:[控制台],
传播:真,
级别:调试,
},
}
}
EMAIL _ HOST= SMTP。电子邮件。QQ。com #如果是163 改成smtp.163.com
EMAIL_PORT=465
EMAIL_HOST_USER= #帐号
EMAIL_HOST_PASSWORD= #密码
#默认发件人电子邮件=电子邮件主机用户
EMAIL_USE_SSL=True
LOGIN_URL=/login/django配置文件
urls.py
URL配置
" urlpatterns "列表将统一资源定位器路由到视图。有关更多信息,请参见:
https://docs.djangoproject.com/en/2.0/topics/http/urls/
示例:
功能视图
1.添加导入:从我的应用程序导入视图
2.将统一资源定位器添加到urlpatterns: path(,views.home,name=home )
基于类的视图
1.添加导入:从其他_应用程序.视图导入主页
2.将统一资源定位器添加到urlpatterns: path(,Home.as_view(),name=home )
包括另一个URLconf
1.导入包括()函数:从django.urls导入包括,路径
2.将统一资源定位器添加到urlpatterns: path(blog/,include(blog.urls ))
来自姜戈. contrib导入管理
从django.urls导入路径,路径
静态导入服务
从博客导入视图
从导入设置
从django.urls导入包括
urlpatterns=[
路径( admin/,admin.site.urls),
路径( login/,views.login),
path(index/,views.index),
path(logout/,views.logout),
re_path(^$,观点指数),
path(get_validCode_img/,views.get_valid_code_img),
path(register/,views.register),
# 文本编辑器上传图片全球资源定位器(统一资源定位器)
路径( upload/,views.upload),
# 后台管理全球资源定位器(统一资源定位器)
re_path(cn_backend/$ ,views.cn_backend),
re _ path( cn _ back end/add _ article/$ ,views.add_article),
# 点赞
path(digg/,views.digg),
# 评论
path(comment/,views.comment),
# 获取评论树相关数据
path(get_comment_tree/,views.get_comment_tree),
#媒体配置:
re_path(rmedia/(?p路径. *)$ ,serve,{document_root :设置. MEDIA_ROOT}),
re_path(^(?p用户名\ w)/文章/(?P article_id \d )$ ,views.article_detail),# article_detail(request,username=袁,‘文章标识’:文章标识)
# 个人站点的跳转
re_path(^(?p用户名\w )/(?p条件标签类别存档)/(?参数p .*)/$ ,views.home_site),# home_site(reqeust,username=yuan ,condition=tag ,param=python )
# 个人站点全球资源定位器(统一资源定位器)
re_path(^(?P username \w )/$ ,views.home_site),# home_site(reqeust,username=yuan )
]路由控制器
模板文件配置模板文件夹
{% extends base.html %}
{%阻止内容%}
{% csrf_token %}
差异
h3 {{ article_obj.title }} /h3
差异
{{ article_obj.contentsafe }}
/div
差异
div id=div_digg
差异
span id= Digg _ count { article _ obj。向上计数} }/span
/div
差异
span id= bury _ count { article _ obj。向下计数} }/span
/div
分区/分区
div id=digg_tips /div
/div
/div
差异
p评论树/p
差异
/div
脚本
$.ajax({
URL:"/get _ comment _ tree/",
键入:获取,
数据:{
article _ id:“{ { article _ obj。PK } } "
},
成功:函数(comment_list) {
控制台。log(comment _ list);
$.each(comment_list,function (index,comment_object) {
var pk=comment _ object.pk
定义变量内容=注释_对象.内容
var parent _ comment _ id=comment _ object。parent _ comment _ id
var s= div comment _ id= PK span content /span/div
如果(!parent_comment_id) {
$(.评论_树’).追加;
}否则{
$([comment _ id= parent _ comment _ id ]).追加;
}
})
}
})
/脚本
p评论列表/p
保险商实验所
{ % for comment _ list % }中的注释
里
差异
a href= # {{ forloop.counter }}楼/a nbsp .不间断空格
span { { comment。create _ time date: Y-m-d H:I } } .不间断空格
a href= span { { comment。用户。用户名} }/span/a
用户名={{ comment.user.username }}
comment_pk={{ comment.pk }} 回复/a
/div
{ % if评论。parent _ comment _ id % }
差异
p
{ {评论。家长_评论。用户。用户名} }:{ {评论。家长_评论。内容} }
/p
/div
{% endif %}
差异
p {{ comment.content }} /p
/div
/李
{% endfor %}
/ul
p发表评论/p
p昵称:input type= text id= tbCommentAuthor disabled= disabled size= 50
value= { { request。用户。用户名} }
/p
p评论内容:/p
textarea name= id= comment _ content cols= 60 rows= 10 /textarea
p
按钮提交评论/按钮
/p
/div
脚本
//点赞请求
$(#div_digg .动作)。单击(函数(){
定义变量是_up=$(这个)。有类(“diggit”);
$obj=$(这个)。孩子(“span”);
$.ajax({
URL:"/Digg/",
类型: post ,
数据:{
csrfmiddlewaretoken :$([name= csrfmiddlewaretoken ]).val(),
is_up: is_up,
article _ id :{ { article _ obj。PK } } ,
},
成功:函数(数据){
console.log(数据);
if (data.state) {
var val=parse int(obj。text());
$ obj。文本(值1);
}
否则{
var val=data.handled?您已经推荐过!: 您已经反对过!;
$(#digg_tips ).html(val);
setTimeout(function () {
$(#digg_tips ).html(" ")
}, 1000)
}
}
})
})
//评论请求
var PID=
$(.评论_ BTN) .单击(函数(){
var content=$(#comment_content ).val();
if (pid) {
var指数=内容。的索引( \ n );
内容=内容.切片(索引1)
}
$.ajax({
URL:"/comment/",
类型: post ,
数据:{
csrfmiddlewaretoken :$([name= csrfmiddlewaretoken ]).val(),
article _ id :{ { article _ obj。PK } } ,
内容:内容,
pid: pid
},
成功:函数(数据){
console.log(数据);
定义变量创建时间=数据。创建时间;
定义变量用户名=数据.用户名
变量内容=数据内容
var s=
里
差异
span ${create_time} /span nbsp .不间断空格
a href= span $ { username }/span/a
/div
差异
p ${content} /p
/div
/李
$(ul.comment_list ).追加;
//清空评论框
pid=" ",
$(#comment_content ).val(" ");
}
})
});
//回复按钮事件
$(.回复_ BTN”).单击(函数(){
$(#comment_content ).焦点();
var val=@ $(这个)。属性(用户名) \ n ;
$(#comment_content ).瓦尔(瓦尔);
pid=$(这个)。attr( comment _ PK );
})
/脚本
/div
{ % end block % }文章详细信息。超文本标记语言
!声明文档类型
html lang=en
头
meta charset=UTF-8
标题标题/标题
link rel=样式表 href=/static/blog/CSS/home _ site。 CSS
link rel=样式表 href=/static/theme/{ { blog。主题} }
link rel=样式表 href=/static/blog/CSS/article _ detail。 CSS
link rel=样式表 href=/static/blog/bs/CSS/bootstrap。 CSS
脚本src=/static/js/jquery-3。2 .1 .量滴js /脚本
/头
身体
差异
差异
p
span {{ blog.title }} /span
a href=/cn_backend/管理/a
/p
/div
/div
差异
差异
差异
{% load my_tags %}
{% get_classification_style用户名%}
/div
差异
{%阻止内容%}
{% endblock %}
/div
/div
/div
/body
/html base.html
差异
差异
差异我的标签/div
差异
{ % for tag _ list % }中的标记
p a href=/{{用户名} }/标签/{ {标签。0 } }“{ {标记。0 } }({ { tag。1 } })/应付
{% endfor %}
/div
/div
差异
差异随笔分类/div
差异
{% for cate in cate_list %}
p a href=/{{用户名} }/category/{ cate。0 } }“{ { cate。0 } }({ { cate。1 } })/应付
{% endfor %}
/div
/div
差异
差异随笔归档/div
差异
{ % for date _ list % }中的日期
p a href=/{{用户名} }/archive/{ }日期。0 }} {{日期。0 }}({{日期。1 } })/应付
{% endfor %}
/div
/div
/div classification.html
{% extends base.html %}
{%阻止内容%}
差异
{% for article in article_list %}
div
h5 a href="/{{ article.user.username }}/articles/{{ article.pk }}" {{ article.title }} /a /h5
div
{{ article.desc }}
/div
div
span 发布于 nbsp; nbsp;{{ article.create_timedate:"Y-m-d H:i" }} /span nbsp; nbsp;
span /span 评论({{ article.comment_count }}) nbsp; nbsp;
span /span 点赞({{ article.up_count }}) nbsp; nbsp;
/div
/div
hr
{% endfor %}
/div
{% endblock %}home_site.html
!DOCTYPE html
html lang="en"
head
meta charset="UTF-8"
title Title /title
link rel="stylesheet" href="/static/blog/bs/css/bootstrap.css"
script src="/static/js/jquery-3.2.1.min.js" /script
script src="/static/blog/bs/js/bootstrap.min.js" /script
style
#user_icon {
font-size: 18px;
margin-right: 10px;
vertical-align: -3px;
}
.pub_info{
margin-top: 10px;
}
.pub_info .glyphicon-comment{
vertical-align: -1px;
}
/style
/head
body
nav
div
!-- Brand and toggle get grouped for better mobile display --
div
button type="button" data-toggle="collapse"
data-target="#bs-example-navbar-collapse-1" aria-expanded="false"
span Toggle navigation /span
span /span
span /span
span /span
/button
a href="#" 博客园 /a
/div
!-- Collect the nav links, forms, and other content for toggling --
div id="bs-example-navbar-collapse-1"
ul
li a href="#" 随笔 span (current) /span /a /li
li a href="#" 新闻 /a /li
li a href="#" 博文 /a /li
/ul
ul
{% if request.user.is_authenticated %}
li a href="#" span id="user_icon"
/span {{ request.user.username }} /a /li
li
a href="#" data-toggle="dropdown" role="button" aria-haspopup="true"
aria-expanded="false" Dropdown span /span /a
ul
li a href="#" 修改密码 /a /li
li a href="#" 修改头像 /a /li
li a href="/cn_backend/" 管理 /a /li
li a href="/logout/" 注销 /a /li
li role="separator" /li
li a href="#" Separated link /a /li
/ul
/li
{% else %}
li a href="/login/" 登录 /a /li
li a href="/register/" 注册 /a /li
{% endif %}
/ul
/div !-- /.navbar-collapse --
/div !-- /.container-fluid --
/nav
div
div
div
div
div Panel heading without title /div
div
Panel content
/div
/div
div
div Panel heading without title /div
div
Panel content
/div
/div
div
div Panel heading without title /div
div
Panel content
/div
/div
/div
div
div
{% for article in article_list %}
div
h5 a href="/{{ article.user.username }}/articles/{{ article.pk }}" {{ article.title }} /a /h5
div
span
a href="/{{ article.user.username }}/" img width="56" height="56" src="media/{{ article.user.avatar }}" alt="" /a
/span
span
{{ article.desc }}
/span
/div
div
span a href="/{{ article.user.username }}/" {{ article.user.username }} /a /span nbsp; nbsp; nbsp;
span 发布于 nbsp; nbsp;{{ article.create_timedate:"Y-m-d H:i" }} /span nbsp; nbsp;
span /span 评论({{ article.comment_count }}) nbsp; nbsp;
span /span 点赞({{ article.up_count }}) nbsp; nbsp;
/div
/div
hr
{% endfor %}
/div
/div
div
div
div Panel heading without title /div
div
Panel content
/div
/div
div
div Panel heading without title /div
div
Panel content
/div
/div
/div
/div
/div
/body
/html index.html
!DOCTYPE html
html lang="en"
head
meta charset="UTF-8"
title Title /title
link rel="stylesheet" href="/static/blog/bs/css/bootstrap.css"
/head
body
h3 登录页面 /h3
div
div
div
form
{% csrf_token %}
div
label for="user" 用户名 /label
input type="text" id="user"
/div
div
label for="pwd" 密码 /label
input type="password" id="pwd"
/div
div
label for="pwd" 验证码 /label
div
div
input type="text" id="valid_code"
/div
div
img width="270" height="36" id="valid_code_img" src="/get_validCode_img/" alt=""
/div
/div
/div
input type="button" value="submit" span /span
a href="/register/" 注册 /a
/form
/div
/div
/div
script src="/static/js/jquery-3.2.1.min.js" /script
script
// 刷新验证码
$("#valid_code_img").click(function () {
$(this)[0].src += "?"
});
// 登录验证
$(".login_btn").click(function () {
$.ajax({
url: "",
type: "post",
data: {
user: $("#user").val(),
pwd: $("#pwd").val(),
valid_code: $("#valid_code").val(),
csrfmiddlewaretoken: $("[name=csrfmiddlewaretoken]").val(),
},
success: function (data) {
console.log(data);
if (data.user) {
if (location.search){
location.href = location.search.slice(6)
}
else {
location.href = "/index/"
}
}
else {
$(".error").text(data.msg).css({"color": "red", "margin-left": "10px"});
setTimeout(function(){
$(".error").text("");
},1000)
}
}
})
})
/script
/body
/html login.html
!DOCTYPE html
html lang="en"
head
meta charset="UTF-8"
title Title /title
link rel="stylesheet" href="/static/blog/bs/css/bootstrap.css"
/head
body
div
div
a href="http://www.cnblogs.com/" img src="/static/blog/img/logo_small.gif" alt="cnblogs" /a
p b 404. /b 抱歉! 您访问的资源不存在! /p
p 请确认您输入的网址是否正确,如果问题持续存在,请发邮件至 404042726@qq.com 与 strong 老村长 /strong 联系。 /p
p a href="/" 返回网站首页 /a /p
/div
/div
/body
/html not_found.html
!DOCTYPE html
html lang="en"
head
meta charset="UTF-8"
title Title /title
link rel="stylesheet" href="/static/blog/bs/css/bootstrap.css"
script src="/static/js/jquery-3.2.1.min.js" /script
style
#avatar_img {
margin-left: 20px;
}
#avatar {
display: none;
}
.error {
color: red;
}
/style
/head
body
h3 注册页面 /h3
div
div
div
form id="form"
{% csrf_token %}
{% for field in form %}
div
label for="{{ field.auto_id }}" {{ field.label }} /label
{{ field }} span /span
/div
{% endfor %}
div
label for="avatar"
头像
img id="avatar_img" width="60" height="60" src="/static/blog/img/default.png" alt=""
/label
input type="file" id="avatar" name="avatar"
/div
input type="button" value="submit" span /span
/form
/div
/div
/div
script
// 头像预览
$("#avatar").change(function () {
// 获取用户选中的文件对象
var file_obj = $(this)[0].files[0];
// 获取文件对象的路径
var reader = new FileReader();
reader.readAsDataURL(file_obj);
// 修改img的src属性 ,src=文件对象的路径
reader.onload = function () {
$("#avatar_img").attr("src", reader.result)
};
});
// 基于Ajax提交数据
$(".reg_btn").click(function () {
//console.log($("#form").serializeArray());
var formdata = new FormData();
var request_data = $("#form").serializeArray();
$.each(request_data, function (index, data) {
formdata.append(data.name, data.value)
});
formdata.append("avatar", $("#avatar")[0].files[0]);
$.ajax({
url: "",
type: "post",
contentType: false,
processData: false,
data: formdata,
success: function (data) {
//console.log(data);
if (data.user) {
// 注册成功
location.href="/login/"
}
else { // 注册失败
//console.log(data.msg)
// 清空错误信息
$("span.error").html("");
$(".form-group").removeClass("has-error");
// 展此次提交的错误信息!
$.each(data.msg, function (field, error_list) {
console.log(field, error_list);
if (field=="__all__"){
$("#id_re_pwd").next().html(error_list[0]).parent().addClass("has-error");
}
$("#id_" + field).next().html(error_list[0]);
$("#id_" + field).parent().addClass("has-error");
})
}
}
})
})
/script
/body
/html register.html
backend文件夹
{% extends backend/base.html %}
{% block content %}
form action="" method="post"
{% csrf_token %}
div
div 添加文章 /div
div
div
label for="" 标题 /label
div
input type="text" name="title"
/div
/div
div
label for="" 内容(Kindeditor编辑。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。