1、settings.py
import os
BASE_DIR = os. path. dirname( os. path. dirname( os. path. abspath( __file__) ) )
SECRET_KEY = '$!td*pims7bsnb%&jhfov9x3pq7vrh2)is*8@9+uxpwlrz4de-'
DEBUG = True
ALLOWED_HOSTS = [ ]
INSTALLED_APPS = [
'django.contrib.admin' ,
'django.contrib.auth' ,
'django.contrib.contenttypes' ,
'django.contrib.sessions' ,
'django.contrib.messages' ,
'django.contrib.staticfiles' ,
'blog.apps.BlogConfig' ,
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware' ,
'django.contrib.sessions.middleware.SessionMiddleware' ,
'django.middleware.common.CommonMiddleware' ,
'django.middleware.csrf.CsrfViewMiddleware' ,
'django.contrib.auth.middleware.AuthenticationMiddleware' ,
'django.contrib.messages.middleware.MessageMiddleware' ,
'django.middleware.clickjacking.XFrameOptionsMiddleware' ,
]
ROOT_URLCONF = 'BBS_11_09.urls'
TEMPLATES = [
{
'BACKEND' : 'django.template.backends.django.DjangoTemplates' ,
'DIRS' : [ os. path. join( BASE_DIR, 'templates' ) ]
,
'APP_DIRS' : True ,
'OPTIONS' : {
'context_processors' : [
'django.template.context_processors.debug' ,
'django.template.context_processors.request' ,
'django.contrib.auth.context_processors.auth' ,
'django.contrib.messages.context_processors.messages' ,
] ,
} ,
} ,
]
WSGI_APPLICATION = 'BBS_11_09.wsgi.application'
DATABASES = {
'default' : {
'ENGINE' : 'django.db.backends.sqlite3' ,
'NAME' : os. path. join( BASE_DIR, 'db.sqlite3' ) ,
}
}
AUTH_PASSWORD_VALIDATORS = [
{
'NAME' : 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator' ,
} ,
{
'NAME' : 'django.contrib.auth.password_validation.MinimumLengthValidator' ,
} ,
{
'NAME' : 'django.contrib.auth.password_validation.CommonPasswordValidator' ,
} ,
{
'NAME' : 'django.contrib.auth.password_validation.NumericPasswordValidator' ,
} ,
]
LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/shanghai'
USE_I18N = True
USE_L10N = True
USE_TZ = False
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os. path. join( BASE_DIR, 'static' )
]
MEDIA_ROOT = os. path. join( BASE_DIR, 'media' )
AUTH_USER_MODEL = 'blog.User'
LOGIN_URL = '/login/'
2、urls.py
"""BBS_11_09 URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/2.1/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django. contrib import admin
from django. urls import path, re_path
from blog import views
from django. views. static import serve
from django. conf import settings
urlpatterns = [
path( 'admin/' , admin. site. urls) ,
path( 'register/' , views. register, name= 'register' ) ,
path( 'login/' , views. login, name= 'login' ) ,
path( 'logout/' , views. logout, name= 'logout' ) ,
path( 'get_valid_code/' , views. get_valid, name= 'get_valid' ) ,
path( 'home/' , views. home, name= 'home' ) ,
path( 'comment_content/' , views. comment_content, name= 'comment_content' ) ,
path( 'diggit/' , views. diggit, name= 'diggit' ) ,
path( 'backend/' , views. backend, name= 'backend' ) ,
path( 'change_pwd/' , views. change_pwd, name= 'change_pwd' ) ,
path( 'add_article/' , views. add_article, name= 'add_article' ) ,
path( 'update_head/' , views. update_head, name= 'update_head' ) ,
re_path( '^check_user/' , views. check_user, name= 'check_user' ) ,
re_path( '^delete/(?P<id>\d+)' , views. delete, name= 'delete' ) ,
re_path( '^update_article/(?P<id>\d+)' , views. update_article, name= 'update_article' ) ,
re_path( r'^blogsite/(?P<name>\w+)/(?P<query>category|tag|archive)/(?P<condition>.*?).html$' , views. blogsite) ,
re_path( r'^blogsite/(?P<name>\w+)/$' , views. blogsite, ) ,
re_path( r'^(?P<name>\w+)/article_detail/(?P<id>\d+).html' , views. article_detail) ,
re_path( r'^media/(?P<path>.*)$' , serve, { 'document_root' : settings. MEDIA_ROOT} )
]
3、templatags.py
from django. template import library
from blog import models
from django. db. models import Count
from django. db. models. functions import TruncMonth
register = library. Library( )
@register. inclusion_tag( 'left.html' )
def left ( name) :
user = models. User. objects. filter ( username= name) . first( )
category_list = models. Category. objects. filter ( blog= user. blog) . annotate( num= Count( 'article__id' ) ) . values_list(
'name' ,
'num' ,
'id' )
tag_list = models. Tag. objects. filter ( blog= user. blog) . annotate( num= Count( 'article__id' ) ) . values_list( 'name' , 'num' ,
'id' )
month_list = models. Article. objects. filter ( blog= user. blog) . annotate( month= TruncMonth( 'create_time' ) ) . values(
'month' ) . annotate( num= Count( 'pk' ) ) . order_by( '-month' ) . values_list( 'month' , 'num' )
return { 'name' : name, 'category_list' : category_list, 'tag_list' : tag_list, 'month_list' : month_list}
@register. inclusion_tag( 'backend/backleft.html' )
def backleft ( request) :
res_category = models. Category. objects. filter ( blog= request. user. blog) . annotate( num= Count( 'article__id' ) ) . values_list(
'name' , 'num' , 'id' )
name = request. user. username
return { 'res_category' : res_category, 'name' : name}
4、blogform.py
from django import forms
from django. forms import widgets
class UserForm ( forms. Form) :
username = forms. CharField( max_length= 18 , min_length= 3 , label= '用户名' ,
widget= widgets. TextInput( attrs= { 'class' : 'form-control' } ) , error_messages= {
'max_length' : '最长18位' , 'min_length' : '最短3位' , 'required' : '该字段必填'
} )
password = forms. CharField( max_length= 18 , min_length= 3 , label= '密码' ,
widget= widgets. PasswordInput( attrs= { 'class' : 'form-control' } ) , error_messages= {
'max_length' : '最长18位' , 'min_length' : '最短3位' , 'required' : '该字段必填'
} )
re_password = forms. CharField( max_length= 18 , min_length= 3 , label= '确认密码' ,
widget= widgets. PasswordInput( attrs= { 'class' : 'form-control' } ) , error_messages= {
'max_length' : '最长18位' , 'min_length' : '最短3位' , 'required' : '该字段必填'
} )
email = forms. EmailField( label= '邮箱' , widget= widgets. EmailInput( attrs= { 'class' : 'form-control' } ) ,
error_messages= { 'required' : '该字段必填' , 'invalid' : '格式不正确' } )
phone = forms. CharField( max_length= 18 , min_length= 3 , label= '手机号' ,
widget= widgets. TextInput( attrs= { 'class' : 'form-control' } ) , error_messages= {
'max_length' : '最长18位' , 'min_length' : '最短3位' , 'required' : '该字段必填'
} )
def clean ( self) :
password = self. cleaned_data. get( 'password' )
re_password = self. cleaned_data. get( 're_password' )
if password != re_password:
self. add_error( 're_password' , '两次密码不一致' )
return self. cleaned_data
5、models.py
from django. db import models
from django. contrib. auth. models import AbstractUser
class User ( AbstractUser) :
phone = models. CharField( max_length= 15 , verbose_name= '电话号码' )
head = models. FileField( default= 'head/default.png' , upload_to= 'head/' , verbose_name= '头像' )
blog = models. OneToOneField( to= 'Blog' , verbose_name= '关联博客' , on_delete= models. CASCADE, null= True )
class Blog ( models. Model) :
site_title = models. CharField( max_length= 32 , verbose_name= '站点标题' )
site_name = models. CharField( max_length= 32 , verbose_name= '站点名称' )
site_style = models. CharField( max_length= 32 , verbose_name= '站点样式' )
def __str__ ( self) :
return self. site_title
class Category ( models. Model) :
name = models. CharField( max_length= 32 , verbose_name= '分类名称' )
blog = models. ForeignKey( to= 'Blog' , verbose_name= '关联博客' , on_delete= models. CASCADE)
def __str__ ( self) :
return self. name
class Tag ( models. Model) :
name = models. CharField( max_length= 32 , verbose_name= '标签名称' )
blog = models. ForeignKey( to= 'Blog' , verbose_name= '关联博客' , on_delete= models. CASCADE)
def __str__ ( self) :
return self. name
class Article ( models. Model) :
name = models. CharField( max_length= 32 , verbose_name= '文章名称' )
description = models. CharField( max_length= 128 , verbose_name= '文章描述' )
content = models. TextField( verbose_name= '文章内容' )
create_time = models. DateTimeField( auto_now_add= True , null= True )
up_num = models. IntegerField( verbose_name= '点赞数' , default= 0 )
down_num = models. IntegerField( verbose_name= '点踩数' , default= 0 )
commit_num = models. IntegerField( verbose_name= '评论数' , default= 0 )
blog = models. ForeignKey( to= 'Blog' , verbose_name= '关联博客' , on_delete= models. CASCADE, null= True )
category = models. ForeignKey( to= 'Category' , verbose_name= '关联分类' , on_delete= models. CASCADE)
tag = models. ManyToManyField( to= 'Tag' , verbose_name= '关联标签' )
def __str__ ( self) :
return self. name
class Commit ( models. Model) :
content = models. CharField( max_length= 128 , verbose_name= '评论内容' )
create_time = models. DateTimeField( auto_now_add= True )
user = models. ForeignKey( to= 'User' , verbose_name= '关联用户' , on_delete= models. CASCADE)
article = models. ForeignKey( to= 'Article' , verbose_name= '关联文章' , on_delete= models. CASCADE)
commit_self = models. ForeignKey( to= 'self' , verbose_name= '子评论' , on_delete= models. CASCADE, null= True )
class UpAndDown ( models. Model) :
user = models. ForeignKey( to= 'User' , verbose_name= '关联用户' , on_delete= models. CASCADE)
article = models. ForeignKey( to= 'Blog' , verbose_name= '关联文章' , on_delete= models. CASCADE)
is_up = models. BooleanField( verbose_name= '点赞点踩' )
6、utils.py
class Pagination ( object ) :
def __init__ ( self, current_page, all_count, per_page_num= 2 , pager_count= 11 ) :
"""
封装分页相关数据
:param current_page: 当前页
:param all_count: 数据库中的数据总条数
:param per_page_num: 每页显示的数据条数
:param pager_count: 最多显示的页码个数
"""
try :
current_page = int ( current_page)
except Exception as e:
current_page = 1
if current_page < 1 :
current_page = 1
self. current_page = current_page
self. all_count = all_count
self. per_page_num = per_page_num
all_pager, tmp = divmod ( all_count, per_page_num)
if tmp:
all_pager += 1
self. all_pager = all_pager
self. pager_count = pager_count
self. pager_count_half = int ( ( pager_count - 1 ) / 2 )
@property
def start ( self) :
return ( self. current_page - 1 ) * self. per_page_num
@property
def end ( self) :
return self. current_page * self. per_page_num
def page_html ( self) :
if self. all_pager <= self. pager_count:
pager_start = 1
pager_end = self. all_pager + 1
else :
if self. current_page <= self. pager_count_half:
pager_start = 1
pager_end = self. pager_count + 1
else :
if ( self. current_page + self. pager_count_half) > self. all_pager:
pager_end = self. all_pager + 1
pager_start = self. all_pager - self. pager_count + 1
else :
pager_start = self. current_page - self. pager_count_half
pager_end = self. current_page + self. pager_count_half + 1
page_html_list = [ ]
page_html_list. append( '''
<nav aria-label='Page navigation>'
<ul class='pagination'>
''' )
first_page = '<li><a href="?page=%s">首页</a></li>' % ( 1 )
page_html_list. append( first_page)
if self. current_page <= 1 :
prev_page = '<li class="disabled"><a href="#">上一页</a></li>'
else :
prev_page = '<li><a href="?page=%s">上一页</a></li>' % ( self. current_page - 1 , )
page_html_list. append( prev_page)
for i in range ( pager_start, pager_end) :
if i == self. current_page:
temp = '<li class="active"><a href="?page=%s">%s</a></li>' % ( i, i, )
else :
temp = '<li><a href="?page=%s">%s</a></li>' % ( i, i, )
page_html_list. append( temp)
if self. current_page >= self. all_pager:
next_page = '<li class="disabled"><a href="#">下一页</a></li>'
else :
next_page = '<li><a href="?page=%s">下一页</a></li>' % ( self. current_page + 1 , )
page_html_list. append( next_page)
last_page = '<li><a href="?page=%s">尾页</a></li>' % ( self. all_pager, )
page_html_list. append( last_page)
page_html_list. append( '''
</nav>
</ul>
''' )
return '' . join( page_html_list)
7、views.py
import random
import json
import os
from django. shortcuts import render, HttpResponse, redirect, reverse
from blog import blogform, models, utils
from django. http import JsonResponse
from PIL import Image, ImageFont, ImageDraw
from io import BytesIO
from django. contrib import auth
from django. contrib. auth. decorators import login_required
from django. db. models import Count, F
from django. db import transaction
from bs4 import BeautifulSoup
from django. views. decorators. csrf import csrf_exempt
from django. conf import settings
def check_user ( request) :
dic = { 'code' : 100 , 'msg' : '用户名合格' }
username = request. GET. get( 'name' )
print ( username)
user = models. User. objects. filter ( username= username) . count( )
if user:
dic[ 'code' ] = 101
dic[ 'msg' ] = '该用户已存在'
return JsonResponse( dic)
def register ( request) :
if request. method == 'GET' :
form = blogform. UserForm( )
return render( request, 'register.html' , { 'form' : form} )
else :
dic = { 'code' : 100 , 'msg' : '创建成功' }
form = blogform. UserForm( request. POST)
if form. is_valid( ) :
data = form. cleaned_data
file = request. FILES. get( 'head' )
user = models. User. objects. filter ( username= data. get( 'username' ) ) . count( )
if user:
dic[ 'code' ] = 102
dic[ 'msg' ] = '用户已存在'
else :
if file :
data[ 'head' ] = file
data. pop( 're_password' )
models. User. objects. create_user( ** data)
dic[ 'url' ] = reverse( 'login' )
else :
dic[ 'code' ] = 101
dic[ 'error' ] = form. errors
return JsonResponse( dic)
def get_rgb ( ) :
return ( random. randint( 0 , 255 ) , random. randint( 0 , 255 ) , random. randint( 0 , 255 ) )
def get_valid ( request) :
img = Image. new( 'RGB' , ( 160 , 50 ) , ( 255 , 255 , 255 ) )
img_draw = ImageDraw. Draw( img)
img_font = ImageFont. truetype( './static/font/stratum2black.otf' , 40 )
valid_code = ''
for i in range ( 5 ) :
low_chr = chr ( random. randint( 97 , 122 ) )
num = random. randint( 0 , 9 )
upper_chr = chr ( random. randint( 65 , 90 ) )
res = str ( random. choice( [ low_chr, num, upper_chr] ) )
valid_code += res
img_draw. text( ( i * 30 + 10 , 8 ) , res, get_rgb( ) , img_font)
request. session[ 'valid_code' ] = valid_code
width = 160
height = 50
for i in range ( 3 ) :
x1 = random. randint( 0 , width)
x2 = random. randint( 0 , width)
y1 = random. randint( 0 , height)
y2 = random. randint( 0 , height)
img_draw. line( ( x1, y1, x2, y2) , fill= get_rgb( ) )
for i in range ( 50 ) :
img_draw. point( [ random. randint( 0 , width) , random. randint( 0 , height) ] , fill= get_rgb( ) )
x = random. randint( 0 , width)
y = random. randint( 0 , height)
img_draw. arc( ( x, y, x + 4 , y + 4 ) , 0 , 90 , fill= get_rgb( ) )
f = BytesIO( )
img. save( f, 'png' )
data = f. getvalue( )
return HttpResponse( data)
def login ( request) :
if request. method == 'GET' :
return render( request, 'login.html' )
else :
dic = { 'code' : 100 , 'msg' : '' }
username = request. POST. get( 'username' )
password = request. POST. get( 'password' )
valid_code = request. POST. get( 'valid_code' )
print ( valid_code)
if valid_code. lower( ) == request. session. get( 'valid_code' ) . lower( ) :
user = auth. authenticate( username= username, password= password)
if user:
auth. login( request, user)
dic[ 'url' ] = reverse( 'home' )
else :
dic[ 'code' ] = 101
dic[ 'msg' ] = '用户名或密码错误'
else :
dic[ 'code' ] = 102
dic[ 'msg' ] = '验证码错误'
return JsonResponse( dic)
def logout ( request) :
if request. user. is_authenticated:
auth. logout( request)
return redirect( reverse( 'home' ) )
def change_pwd ( request) :
dic = { 'code' : 100 , 'message' : '' }
if request. is_ajax( ) :
old_pwd = request. POST. get( 'old_pwd' )
new_pwd = request. POST. get( 'new_pwd' )
re_new_pwd = request. POST. get( 're_new_pwd' )
if request. user. check_password( old_pwd) :
if new_pwd == re_new_pwd:
request. user. set_password( new_pwd)
dic[ 'message' ] = '修改成功'
dic[ 'url' ] = reverse( 'login' )
else :
dic[ 'code' ] = 101
dic[ 'message' ] = '两次密码不一致'
else :
dic[ 'code' ] = 102
dic[ 'message' ] = '旧密码不正确'
return JsonResponse( dic)
def home ( request) :
if request. method == 'GET' :
ll = [ { 'url' : 'http://www.baidu.com' ,
'img_url' : '/static/img/banner1.jpg' ,
'message' : '火热广告招商' } ,
{ 'url' : 'http://www.bilibili.com' ,
'img_url' : '/static/img/banner2.jpg' ,
'message' : '体验游戏人生' } ,
{ 'url' : 'http://www.xiaomi.com' ,
'img_url' : '/static/img/banner3.jpg' ,
'message' : '点我有你好看' } ,
]
article_list = models. Article. objects. all ( ) . order_by( '-create_time' )
current_page = request. GET. get( 'page' , 1 )
all_count = article_list. count( )
page_obj = utils. Pagination( current_page= current_page, all_count= all_count, per_page_num= 2 )
page_queryset = article_list[ page_obj. start: page_obj. end]
return render( request, 'home.html' , { 'page_obj' : page_obj, 'page_queryset' : page_queryset, 'll' : ll} )
def blogsite ( request, name, ** kwargs) :
if request. method == 'GET' :
user = models. User. objects. filter ( username= name) . first( )
if user:
article_list = models. Article. objects. filter ( blog= user. blog)
query = kwargs. get( 'query' )
condition = kwargs. get( 'condition' )
if query == 'category' :
article_list = models. Article. objects. filter ( category_id= condition)
elif query == 'tag' :
article_list = models. Article. objects. filter ( tag__id= condition)
elif query == 'archive' :
year, month = kwargs. get( 'condition' ) . split( '/' )
article_list = models. Article. objects. filter ( create_time__year= year, create_time__month= month)
current_page = request. GET. get( 'page' , 1 )
all_count = article_list. count( )
page_obj = utils. Pagination( current_page= current_page, all_count= all_count, per_page_num= 2 )
page_queryset = article_list[ page_obj. start: page_obj. end]
return render( request, 'blogsite.html' , locals ( ) )
else :
return HttpResponse( '404' )
def article_detail ( request, name, id ) :
if request. method == 'GET' :
user = models. User. objects. filter ( username= name) . first( )
if user:
article = models. Article. objects. get( id = id )
commit_list = models. Commit. objects. filter ( user_id= user. id )
return render( request, 'article_detail.html' ,
{ 'user' : user, 'article' : article, 'commit_list' : commit_list} )
def diggit ( request) :
if request. is_ajax( ) :
dic = { 'code' : 100 , 'msg' : '' }
if request. user. is_authenticated:
is_up = json. loads( request. POST. get( 'is_up' ) )
article_id = request. POST. get( 'article_id' )
user = request. user
res = models. UpAndDown. objects. filter ( article_id= article_id, user_id= user. id ) . count( )
if res:
dic[ 'code' ] = 102
dic[ 'msg' ] = '已评论,无法再次评论'
else :
with transaction. atomic( ) :
models. UpAndDown. objects. create( is_up= is_up, article_id= article_id, user_id= user. id )
if is_up:
models. Article. objects. filter ( id = article_id) . update( up_num= F( 'up_num' ) + 1 )
dic[ 'msg' ] = '点赞成功'
else :
models. Article. objects. filter ( id = article_id) . update( down_num= F( 'down_num' ) + 1 )
dic[ 'msg' ] = '点踩成功'
else :
dic[ 'code' ] = 101
dic[ 'msg' ] = '请先<a href="/login/">登录</a>'
return JsonResponse( dic)
def comment_content ( request) :
dic = { 'code' : 100 , 'msg' : '' }
if request. is_ajax( ) :
if request. user. is_authenticated:
content = request. POST. get( 'commit' )
article_id = request. POST. get( 'article_id' )
parent_id = request. POST. get( 'parent_id' )
user = request. user
with transaction. atomic( ) :
if parent_id:
commits = models. Commit. objects. create( article_id= article_id, user_id= user. id , content= content,
commit_self_id= parent_id)
else :
commits = models. Commit. objects. create( article_id= article_id, user_id= user. id , content= content)
models. Article. objects. filter ( id = article_id) . update( commit_num= F( 'commit_num' ) + 1 )
dic[ 'content' ] = commits. content
dic[ 'msg' ] = '评论成功'
dic[ 'username' ] = user. username
if parent_id:
dic[ 'parent_name' ] = commits. commit_self. user. username
else :
dic[ 'code' ] = 101
dic[ 'msg' ] = '请先<a href="/login/">登录</a>'
return JsonResponse( dic)
@login_required
def backend ( request) :
if request. method == 'GET' :
if request. user. is_authenticated:
article_list = models. Article. objects. filter ( blog= request. user. blog)
current_page = request. GET. get( 'page' , 1 )
all_count = article_list. count( )
page_obj = utils. Pagination( current_page= current_page, all_count= all_count, per_page_num= 2 )
page_queryset = article_list[ page_obj. start: page_obj. end]
return render( request, 'backend/backend.html' , locals ( ) )
@login_required
def add_article ( request) :
if request. method == 'GET' :
category_list = models. Category. objects. filter ( blog= request. user. blog)
tag_list = models. Tag. objects. filter ( blog= request. user. blog)
return render( request, 'backend/add_article.html' , locals ( ) )
else :
name = request. POST. get( 'name' )
content = request. POST. get( 'content' )
category_id = request. POST. get( 'category' )
description = content[ : 20 ]
tag_list = request. POST. getlist( 'tag' )
soup = BeautifulSoup( content, 'html.parser' )
description = soup. text[ : 30 ]
res_script = soup. find_all( 'script' )
for script in res_script:
script. decompose( )
article = models. Article. objects. create( name= name, content= str ( soup) , category_id= category_id,
blog= request. user. blog,
description= description)
article. tag. add( tag_list)
return redirect( reverse( 'backend' ) )
@csrf_exempt
def upload_img ( request) :
dic = { 'error' : 0 }
try :
file = request. FILES. get( 'myfile' )
path = os. path. join( settings. BASE_DIR, 'media' , 'img' , file . name)
with open ( path, 'wb' ) as f:
for line in file . chunks( ) :
f. write( line)
dic[ 'url' ] = '/media/img' + file . name
except Exception as e:
dic[ 'error' ] = 1
dic[ 'message' ] = str ( e)
return JsonResponse( dic)
@login_required
def update_head ( request) :
if request. method == 'GET' :
return render( request, 'backend/update_head.html' )
else :
file = request. FILES. get( 'myhead' )
models. User. objects. filter ( id = request. user. id ) . update( head= file )
return redirect( reverse( 'backend' ) )
@login_required
def delete ( request, id ) :
models. Article. objects. filter ( id = id ) . delete( )
return redirect( reverse( 'backend' ) )
@login_required
def update_article ( request, id ) :
article = models. Article. objects. get( id = id )
if request. method == 'GET' :
category_list = models. Category. objects. filter ( blog= request. user. blog)
tag_list = models. Tag. objects. filter ( blog= request. user. blog)
return render( request, 'backend/update_article.html' , locals ( ) )
else :
name = request. POST. get( 'name' )
content = request. POST. get( 'content' )
category_id = request. POST. get( 'category' )
description = content[ : 20 ]
tag_list = request. POST. getlist( 'tag' )
if len ( tag_list) < 2 :
tag_list = request. POST. get( 'tag' )
soup = BeautifulSoup( content, 'html.parser' )
description = soup. text[ : 30 ]
res_script = soup. find_all( 'script' )
for script in res_script:
script. decompose( )
article. name = name
article. content = content
article. category_id = category_id
article. description = str ( soup)
article. tag. clear( )
article. tag. add( * tag_list)
article. save( )
return redirect( reverse( 'backend' ) )
8、register.html
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< title> 注册界面</ title>
{% load static %}
< script src = " {% static ' jquery-3.3.1/jquery-3.3.1.min.js' %}" > </ script>
< link href = " {% static ' bootstrap/css/bootstrap.min.css' %}" rel = " stylesheet" >
< link href = " {% static ' /font-awesome-4.7.0/font-awesome-4.7.0/css/font-awesome.css' %}" rel = " stylesheet" >
< script src = " {% static ' bootstrap/js/bootstrap.min.js' %}" > </ script>
</ head>
< body>
< div class = " container-fluid" >
< div class = " row" >
< h2 class = " text-center" > 注册界面</ h2>
< div class = " col-md-6 col-md-offset-3" >
< form action = " " enctype = " multipart/form-data" id = " form" novalidate >
{% csrf_token %}
{% for foo in form %}
< div class = " form-group" >
{{ foo.label }}
{{ foo }}
< span class = " text-danger pull-right" > </ span>
</ div>
{% endfor %}
< div class = " form-group" >
< label for = " head" > 头像< img src = " /static/img/default.png" width = " 80" height = " 80" alt = " " id = " head_img" > </ label>
< input type = " file" id = " head" style =" display : none" >
</ div>
< div class = " text-center" >
< button class = " btn-lg btn btn-success " type = " button" id = " btn" > 提交</ button>
</ div>
</ form>
</ div>
</ div>
</ div>
< script>
$ ( '#head' ) . change ( function ( ) {
let fileread = new FileReader ( )
fileread. readAsDataURL ( this . files[ 0 ] )
fileread. onload = function ( ) {
console. log ( fileread. result)
$ ( '#head_img' ) . attr ( 'src' , fileread. result)
}
} )
$ ( '#btn' ) . click ( function ( ) {
let formdata = new FormData ( )
formdata. append ( 'head' , $ ( '#head' ) [ 0 ] . files[ 0 ] )
let formlist = $ ( '#form' ) . serializeArray ( )
$. each ( formlist, function ( k, v) {
formdata. append ( v. name, v. value)
} )
$. ajax ( {
url: '' ,
method: 'post' ,
data: formdata,
processData: false ,
contentType: false ,
success: function ( data) {
if ( data. code === 100 ) {
location. href = data. url
} else {
$. each ( data. error, function ( k, v) {
console. log ( k, v)
$ ( '#id_' + k) . next ( ) . text ( v)
setTimeout ( function ( ) {
$ ( '#id_' + k) . next ( ) . text ( '' )
} , 3000 )
} )
}
}
} )
} )
$ ( '#id_username' ) . blur ( function ( ) {
let name = $ ( this ) . val ( )
$. ajax ( {
url: '/check_user/?name=' + name,
method: 'get' ,
success: function ( data) {
$ ( this ) . next ( ) . text ( data. msg)
setTimeout ( function ( ) {
$ ( this ) . next ( ) . text ( '' )
} , 3000 )
}
} )
} )
</ script>
</ body>
</ html>
9、login.html
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< title> 登录界面</ title>
{% load static %}
< script src = " {% static ' jquery-3.3.1/jquery-3.3.1.min.js' %}" > </ script>
< link href = " {% static ' bootstrap/css/bootstrap.min.css' %}" rel = " stylesheet" >
< script src = " {% static ' bootstrap/js/bootstrap.min.js' %}" > </ script>
</ head>
< body>
< div class = " container-fluid" >
< div class = " row" >
< div class = " col-md-6 col-md-offset-3 " >
< h1 class = " form-signin-heading" style =" color : palevioletred" > 用户登录</ h1>
< form action = " " id = " form" >
{% csrf_token %}
< br>
< div class = " form-group" >
< label style =" font-size : 20px; color : darkturquoise" for = " username" > 账号</ label>
< input type = " text" class = " form-control" name = " username" id = " username" >
</ div>
< div class = " form-group" >
< label style =" font-size : 20px; color : darkturquoise" for = " password" > 密码</ label>
< input type = " password" class = " form-control" name = " password" id = " password" >
</ div>
< br>
< div class = " form-group" >
< label style =" font-size : 20px; color : darkturquoise" for = " valid_code" > 验证码</ label>
< input type = " text" class = " f" name = " valid_code" id = " valid_code" >
< img src = " /get_valid_code/" id = " valid_img" style =" height : 50px; width : 160px" class = " pull-right" >
</ div>
< br>
< div class = " text-center" >
< span class = " text-danger" id = " span_error" > </ span>
< br>
< button type = " button" class = " btn btn-success btn-lg" id = " btn" > 登录</ button>
</ div>
</ form>
</ div>
</ div>
</ div>
< script>
$ ( '#btn' ) . click ( function ( ) {
$. ajax ( {
url: '/login/' ,
method: 'post' ,
data: {
'username' : $ ( '#username' ) . val ( ) ,
'password' : $ ( '#password' ) . val ( ) ,
'csrfmiddlewaretoken' : $ ( '[name="csrfmiddlewaretoken"]' ) . val ( ) ,
'valid_code' : $ ( '#valid_code' ) . val ( )
} ,
success: function ( data) {
if ( data. code !== 100 ) {
$ ( '#span_error' ) . text ( data. msg)
setTimeout ( function ( ) {
$ ( 'span' ) . text ( '' )
} , 3000 )
} else {
location. href = data. url
}
}
} )
} )
$ ( '#valid_img' ) . click ( function ( ) {
var path_img = $ ( this ) . attr ( 'src' ) + '?'
$ ( this ) . attr ( 'src' , path_img)
} )
</ script>
</ body>
</ html>
10、left.html
< div class = " text-center" >
< div class = " panel panel-danger" >
< div class = " panel-heading" >
< h3 class = " panel-title" > 我的标签</ h3>
</ div>
< div class = " panel-body" >
{% for tag in tag_list %}
< p> < a href = " /blogsite/{{ name }}/tag/{{ tag.2 }}.html" > {{ tag.0 }} ({{ tag.1 }})</ a> </ p>
{% endfor %}
</ div>
</ div>
< div class = " panel panel-info" >
< div class = " panel-heading" >
< h3 class = " panel-title" > 随笔分类</ h3>
</ div>
< div class = " panel-body" >
{% for category in category_list %}
< p> < a href = " /blogsite/{{ name }}/category/{{ category.2 }}.html" > {{ category.0 }} ({{ category.1 }})</ a>
</ p>
{% endfor %}
</ div>
</ div>
< div class = " panel panel-primary" >
< div class = " panel-heading" >
< h3 class = " panel-title" > 随笔档案</ h3>
</ div>
{% for month in month_list %}
< p> < a href = " /blogsite/{{ name }}/archive/{{ month.0|date:' Y/m' }}.html" >
{{ month.0|date:'Y年m月' }} ({{ month.1 }})</ a> </ p>
{% endfor %}
</ div>
</ div>
11、home.html
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< title> 博客园首页</ title>
{% load static %}
< script src = " {% static ' jquery-3.3.1/jquery-3.3.1.min.js' %}" > </ script>
< link href = " {% static ' bootstrap/css/bootstrap.min.css' %}" rel = " stylesheet" >
< script src = " {% static ' bootstrap/js/bootstrap.min.js' %}" > </ script>
</ head>
< body>
< div class = " navbar-wrapper" >
< div class = " " >
< nav class = " navbar navbar-inverse navbar-static-top" >
< div id = " navbar" class = " navbar-collapse collapse" >
< ul class = " nav navbar-nav" >
< li> < a href = " #" > 博客园首页</ a> </ li>
< li class = " active" > < a href = " /home/" > 首页</ a> </ li>
< li> < a href = " #" > 历史记录</ a> </ li>
< li style =" margin-left : 100px" >
< form class = " navbar-form navbar-left" role = " search" >
< div class = " form-group" >
< input type = " text" class = " form-control" placeholder = " 输入关键词" >
</ div>
< button type = " submit" class = " btn btn-default btn-warning" > 搜索</ button>
</ form>
</ li>
{% if request.user.is_authenticated %}
< li>
< button type = " button" class = " btn btn-primary" data-toggle = " modal"
style =" margin-top : 10px; margin-left : 450px"
data-target = " #exampleModal" data-whatever = " @mdo" > 修改密码
</ button>
</ li>
< li>
< button id = " logout" type = " button" class = " btn btn-info"
style =" margin-top : 10px; margin-left : 10px" > 注销
</ button>
</ li>
< li>
< button id = " backend" type = " button" class = " btn btn-success"
style =" margin-top : 10px; margin-left : 10px" > 后台管理
</ button>
</ li>
{% else %}
< li>
< button id = " register" type = " button" class = " btn btn-success"
style =" margin-top : 10px; margin-left : 450px" > 注册
</ button>
</ li>
< li>
< button id = " login" type = " button" class = " btn btn-info"
style =" margin-top : 10px; margin-left : 10px" > 登录
</ button>
</ li>
{% endif %}
</ ul>
</ div>
</ nav>
</ div>
</ div>
< div class = " modal fade" id = " exampleModal" tabindex = " -1" role = " dialog"
aria-labelledby = " exampleModalLabel" >
< div class = " modal-dialog" role = " document" >
< div class = " modal-content" >
< div class = " modal-header" >
< button type = " button" class = " close" data-dismiss = " modal" aria-label = " Close" >
< span aria-hidden = " true" > × </ span> </ button>
< h4 class = " modal-title" id = " exampleModalLabel" > 修改密码</ h4>
</ div>
< div class = " modal-body" >
< form id = " form_pwd" >
{% csrf_token %}
< div class = " form-group" >
< label for = " old_pwd" class = " control-label" > 旧密码:
</ label>
< input type = " password" id = " old_pwd" class = " form-control" >
</ div>
< div class = " form-group" >
< label for = " new_pwd" class = " control-label" > 新密码:</ label>
< input type = " password" id = " new_pwd" class = " form-control" >
</ div>
< div class = " form-group" >
< label for = " re_new_pwd" class = " control-label" > 确认新密码:
</ label>
< input type = " password" id = " re_new_pwd" class = " form-control" >
</ div>
</ form>
</ div>
< div class = " text-center" style =" height : 10px" >
< sapn class = " text-danger" > </ sapn>
</ div>
< div class = " modal-footer" >
< button type = " button" class = " btn btn-default" data-dismiss = " modal" > 取消修改
</ button>
< button type = " button" class = " btn btn-primary" id = " btn_pwd" > 提交修改</ button>
</ div>
</ div>
</ div>
</ div>
< div class = " container-fluid" >
< div class = " row" >
< div class = " col-md-2" id = " blog_right" >
< div class = " panel panel-danger" >
< div class = " panel-heading" >
< h3 class = " panel-title" > 关注</ h3>
</ div>
< div class = " panel-body" >
详情点击:< a href = " " > 我评</ a>
< hr>
详情点击:< a href = " " > 我赞</ a>
</ div>
</ div>
< div class = " panel panel-info" >
< div class = " panel-heading" >
< h3 class = " panel-title" > 精华</ h3>
</ div>
< div class = " panel-body" >
详情点击:< a href = " " > 候选</ a>
< hr>
详情点击:< a href = " " > 订阅</ a>
</ div>
</ div>
< div class = " panel panel-primary" >
< div class = " panel-heading" >
< h3 class = " panel-title" > 广告招商</ h3>
</ div>
< div class = " panel-body" >
详情点击:< a href = " " > 百度</ a>
< hr>
详情点击:< a href = " " > 腾讯</ a>
</ div>
</ div>
< div class = " panel panel-primary" >
< div class = " panel-heading" >
< h3 class = " panel-title" > 广告招商</ h3>
</ div>
< div class = " panel-body" >
详情点击:< a href = " " > 百度</ a>
< hr>
详情点击:< a href = " " > 腾讯</ a>
</ div>
</ div>
< div class = " panel panel-primary" >
< div class = " panel-heading" >
< h3 class = " panel-title" > 广告招商</ h3>
</ div>
< div class = " panel-body" >
详情点击:< a href = " " > 百度</ a>
< hr>
详情点击:< a href = " " > 腾讯</ a>
</ div>
</ div>
</ div>
< div class = " col-md-7" id = " blog_middle" >
< div class = " lbt" >
< div id = " carousel-example-generic" class = " carousel slide" data-ride = " carousel" >
< ol class = " carousel-indicators" >
< li data-target = " #carousel-example-generic" data-slide-to = " 0" class = " active" > </ li>
< li data-target = " #carousel-example-generic" data-slide-to = " 1" > </ li>
< li data-target = " #carousel-example-generic" data-slide-to = " 2" > </ li>
</ ol>
< div class = " carousel-inner" role = " listbox" >
< div class = " item active" >
< a href = " {{ ll.0.url }}" class = " a" > < img
src = " {{ ll.0.img_url }}"
alt = " ..." class = " img" > </ a>
< div class = " carousel-caption" style =" font-size : 25px" >
火热广告招商
</ div>
</ div>
< div class = " item" >
< a href = " {{ ll.1.url }}" class = " a" > < img
src = " {{ ll.1.img_url }}"
alt = " ..." class = " img" > </ a>
< div class = " carousel-caption" style =" font-size : 25px" >
体验游戏人生
</ div>
</ div>
< div class = " item" >
< a href = " {{ ll.2.url }}" class = " a" > < img
src = " {{ ll.2.img_url }}"
alt = " ..." class = " img" > </ a>
< div class = " carousel-caption" style =" font-size : 25px" >
点我有你好看
</ div>
</ div>
</ div>
< a class = " left carousel-control" href = " #carousel-example-generic" role = " button"
data-slide = " prev" >
< span class = " glyphicon glyphicon-chevron-left" aria-hidden = " true" > </ span>
< span class = " sr-only" > 上一页</ span>
</ a>
< a class = " right carousel-control" href = " #carousel-example-generic" role = " button"
data-slide = " next" >
< span class = " glyphicon glyphicon-chevron-right" aria-hidden = " true" > </ span>
< span class = " sr-only" > 下一页</ span>
</ a>
</ div>
</ div>
< hr>
< div class = " article" >
{% for article in page_queryset %}
< div class = " media" >
< h4 class = " media-heading" > < a
href = " /{{ article.blog.user.username }}/article_detail/{{ article.id }}.html" > {{ article.name }}</ a>
</ h4>
< div class = " media-left" >
< a href = " /blogsite/{{ article.blog.user.username }}/" >
< img class = " media-object" src = " /media/{{ article.blog.user.head }}" alt = " ..."
width = " 60"
height = " 60" >
</ a>
</ div>
< div class = " media-body" >
{{ article.description }}
</ div>
< div class = " article_bottom " > < span> < a
href = " /blogsite/{{ article.blog.user.username }}/" > {{ article.blog.user.username }}</ a> </ span>
< span> {{ article.create_time|date:'Y-m-d H-i-s' }}</ span>
< span> < i class = " fa fa-thumbs-up fa-lg" > </ i> {{ article.up_num }}</ span>
< span class = " " > < i
class = " fa fa-commenting-o fa-lg" > </ i> {{ article.commit_num }}</ span>
</ div>
</ div>
{% endfor %}
< div class = " text-center" > {{ page_obj.page_html|safe }}</ div>
</ div>
</ div>
< div class = " col-md-3" id = " blog_left" >
< div class = " panel panel-info" >
< div class = " panel-heading" >
< h3 class = " panel-title" > 关注</ h3>
</ div>
< div class = " panel-body" >
详情点击:< a href = " " > 我评</ a>
< hr>
详情点击:< a href = " " > 我赞</ a>
</ div>
</ div>
< div class = " panel panel-success" >
< div class = " panel-heading" >
< h3 class = " panel-title" > 精华</ h3>
</ div>
< div class = " panel-body" >
详情点击:< a href = " " > 候选</ a>
< hr>
详情点击:< a href = " " > 订阅</ a>
</ div>
</ div>
< div class = " panel panel-warning" >
< div class = " panel-heading" >
< h3 class = " panel-title" > 广告招商</ h3>
</ div>
< div class = " panel-body" >
详情点击:< a href = " " > 百度</ a>
< hr>
详情点击:< a href = " " > 腾讯</ a>
</ div>
</ div>
</ div>
</ div>
</ div>
< script>
$ ( "#register" ) . click ( function ( ) {
window. open ( '/register/' , "_self" )
} )
$ ( "#login" ) . click ( function ( ) {
window. open ( '/login/' , "_self" )
} )
$ ( "#backend" ) . click ( function ( ) {
window. open ( '/backend/' , "_self" )
} )
$ ( "#logout" ) . click ( function ( ) {
window. open ( '/logout/' , "_self" )
} )
$ ( '#btn_pwd' ) . click ( function ( ) {
$ ( this ) . prop ( 'disabled' , true )
$. ajax ( {
url: '/change_pwd/' ,
method: 'post' ,
data: {
'old_pwd' : $ ( '#old_pwd' ) . val ( ) ,
'new_pwd' : $ ( '#new_pwd' ) . val ( ) ,
're_new_pwd' : $ ( '#re_new_pwd' ) . val ( ) ,
'csrfmiddlewaretoken' : $ ( '[name="csrfmiddlewaretoken"]' ) . val ( )
} ,
success: function ( data) {
$ ( '#btn_pwd' ) . prop ( 'disabled' , false )
if ( data. code === 100 ) {
$ ( '.text-danger' ) . text ( data. message)
setTimeout ( function ( ) {
location. href = data. url
} , 5000 )
} else {
$ ( '.text-danger' ) . text ( data. message)
$ ( ':password' ) . val ( '' )
setTimeout ( function ( ) {
$ ( '.text-danger' ) . text ( '' )
} , 3000 )
}
}
} )
} )
</ script>
</ body>
</ html>
12、blogsite.html
{% extends 'base.html' %}
{% block title %}
{{ user.username }}的博客
{% endblock %}
{% block style %}
< style>
body {
background-color : rgba ( 0,191,255,0.31) ;
}
</ style>
{% endblock %}
{% block core %}
< div class = " container-fluid" >
< div class = " row" >
< div class = " col-md-2" >
{% load blogsiteleft %}
{% left user.username %}
</ div>
< div class = " col-md-9 col-md-offset-1" >
< div class = " page-header" >
< h1> {{ user.username }}< small> </ small> </ h1>
</ div>
< div class = " article" >
{% for article in page_queryset %}
< div class = " media" >
< h4 class = " media-heading" > < a
href = " /{{ user.username }}/article_detail/{{ article.id }}.html/" > {{ article.name }}</ a>
</ h4>
< div class = " media-body" >
{{ article.description }}
</ div>
< div class = " article_bottom " > < span> < a
href = " /blogsite/{{ article.blog.user.username }}/" > {{ article.blog.user.username }}</ a> </ span>
< span> {{ article.create_time|date:'Y-m-d H-i-s' }}</ span>
< span> < i class = " fa fa-thumbs-up fa-lg" > </ i> {{ article.up_num }}</ span>
< span class = " " > < i
class = " fa fa-commenting-o fa-lg" > </ i> {{ article.commit_num }}</ span>
< span> < a href = " " > < i class = " fa fa-eraser fa-lg" > </ i> 编辑</ a> </ span>
</ div>
</ div>
< hr>
{% endfor %}
< div class = " text-center" > {{ page_obj.page_html|safe }}</ div>
</ div>
</ div>
</ div>
</ div>
{% endblock %}
13、base.html
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< title>
{% block title %}
{% endblock %}
</ title>
{% load static %}
< script src = " {% static ' jquery-3.3.1/jquery-3.3.1.min.js' %}" > </ script>
< link href = " {% static ' bootstrap/css/bootstrap.min.css' %}" rel = " stylesheet" >
< link href = " {% static ' font-awesome-4.7.0/font-awesome-4.7.0/css/font-awesome.css' %}" rel = " stylesheet" >
< script src = " {% static ' bootstrap/js/bootstrap.min.js' %}" > </ script>
{% block css %}
{% endblock %}
{% block style %}
{% endblock %}
</ head>
< body>
< div class = " navbar-wrapper" >
< div class = " " >
< nav class = " navbar navbar-inverse navbar-static-top" >
< div id = " navbar" class = " navbar-collapse collapse" >
< ul class = " nav navbar-nav" >
< li> < a href = " #" >
{% block innertitle %}
{% endblock %}
</ a> </ li>
< li class = " active" > < a href = " /home/" > 首页</ a> </ li>
< li> < a href = " #" > 历史记录</ a> </ li>
< li style =" margin-left : 100px" >
< form class = " navbar-form navbar-left" role = " search" >
< div class = " form-group" >
< input type = " text" class = " form-control" placeholder = " 输入关键词" >
</ div>
< button type = " submit" class = " btn btn-default btn-warning" > 搜索</ button>
</ form>
</ li>
{% if request.user.is_authenticated %}
< li>
< button type = " button" class = " btn btn-primary" data-toggle = " modal"
style =" margin-top : 10px; margin-left : 450px"
data-target = " #exampleModal" data-whatever = " @mdo" > 修改密码
</ button>
</ li>
< li>
< button id = " logout" type = " button" class = " btn btn-info"
style =" margin-top : 10px; margin-left : 10px" > 注销
</ button>
</ li>
< li>
< button id = " backend" type = " button" class = " btn btn-success"
style =" margin-top : 10px; margin-left : 10px" > 后台管理
</ button>
</ li>
{% else %}
< li>
< button id = " register" type = " button" class = " btn btn-success"
style =" margin-top : 10px; margin-left : 450px" > 注册
</ button>
</ li>
< li>
< button id = " login" type = " button" class = " btn btn-info"
style =" margin-top : 10px; margin-left : 10px" > 登录
</ button>
</ li>
{% endif %}
</ ul>
</ div>
</ nav>
</ div>
</ div>
< div class = " modal fade" id = " exampleModal" tabindex = " -1" role = " dialog"
aria-labelledby = " exampleModalLabel" >
< div class = " modal-dialog" role = " document" >
< div class = " modal-content" >
< div class = " modal-header" >
< button type = " button" class = " close" data-dismiss = " modal" aria-label = " Close" >
< span aria-hidden = " true" > × </ span> </ button>
< h4 class = " modal-title" id = " exampleModalLabel" > 修改密码</ h4>
</ div>
< div class = " modal-body" >
< form id = " form_pwd" >
{% csrf_token %}
< div class = " form-group" >
< label for = " old_pwd" class = " control-label" > 旧密码:
</ label>
< input type = " password" id = " old_pwd" class = " form-control" >
</ div>
< div class = " form-group" >
< label for = " new_pwd" class = " control-label" > 新密码:</ label>
< input type = " password" id = " new_pwd" class = " form-control" >
</ div>
< div class = " form-group" >
< label for = " re_new_pwd" class = " control-label" > 确认新密码:
</ label>
< input type = " password" id = " re_new_pwd" class = " form-control" >
</ div>
</ form>
</ div>
< div class = " text-center" style =" height : 10px" >
< span class = " text-danger" > </ span>
</ div>
< div class = " modal-footer" >
< button type = " button" class = " btn btn-default" data-dismiss = " modal" > 取消修改
</ button>
< button type = " button" class = " btn btn-primary" id = " btn_pwd" > 提交修改</ button>
</ div>
</ div>
</ div>
</ div>
{% block core %}
{% endblock %}
< script>
$ ( "#register" ) . click ( function ( ) {
window. open ( '/register/' , "_self" )
} )
$ ( "#login" ) . click ( function ( ) {
window. open ( '/login/' , "_self" )
} )
$ ( "#backend" ) . click ( function ( ) {
window. open ( '/backend/' , "_self" )
} )
$ ( "#logout" ) . click ( function ( ) {
window. open ( '/logout/' , "_self" )
} )
$ ( '#btn_pwd' ) . click ( function ( ) {
$ ( this ) . prop ( 'disabled' , true )
$. ajax ( {
url: '/change_pwd/' ,
method: 'post' ,
data: {
'old_pwd' : $ ( '#old_pwd' ) . val ( ) ,
'new_pwd' : $ ( '#new_pwd' ) . val ( ) ,
're_new_pwd' : $ ( '#re_new_pwd' ) . val ( ) ,
'csrfmiddlewaretoken' : $ ( '[name="csrfmiddlewaretoken"]' ) . val ( )
} ,
success: function ( data) {
$ ( '#btn_pwd' ) . prop ( 'disabled' , false )
if ( data. code === 100 ) {
$ ( '.text-danger' ) . text ( data. message)
setTimeout ( function ( ) {
location. href = data. url
} , 5000 )
} else {
$ ( '.text-danger' ) . text ( data. message)
$ ( ':password' ) . val ( '' )
setTimeout ( function ( ) {
$ ( '.text-danger' ) . text ( '' )
} , 3000 )
}
}
} )
} )
</ script>
{% block js %}
{% endblock %}
</ body>
</ html>
14、articledetail.html
{% extends 'base.html' %}
{% block title %}
{{ user.username }}的博客
{% endblock %}
{% block css %}
< link rel = " stylesheet" href = ' /static/css/mycss.css' >
{% endblock %}
{% block style %}
< style>
body {
background-color : rgba ( 0, 191, 255, 0.31) ;
}
</ style>
{% endblock %}
{% block core %}
< div class = " container-fluid" >
< div class = " row" >
< div class = " col-md-2" >
{% load blogsiteleft %}
{% left user.username %}
</ div>
< div class = " col-md-9 col-md-offset-1" >
< div class = " page-header" >
< h1> {{ article.name }}< small> </ small> </ h1>
</ div>
< div>
{{ article.content }}
</ div>
< div>
< div class = " clearfix" >
< div id = " div_digg" >
< div class = " diggit action" >
< span class = " diggnum" id = " digg_count" > {{ article.up_num }}</ span>
</ div>
< div class = " buryit action" >
< span class = " burynum" id = " bury_count" > {{ article.down_num }}</ span>
</ div>
< div class = " clear" > </ div>
< div class = " diggword" id = " digg_tips" style =" color : red; " >
</ div>
</ div>
</ div>
</ div>
< hr>
< div>
< p> 评论列表</ p>
< ul class = " list-group" >
{% for commit in commit_list %}
< li class = " list-group-item" >
< div>
< span> #{{ forloop.counter }}楼</ span>
< span> {{ commit.create_time|date:'Y-m-d H-i' }}</ span>
< span> < a
href = " /blogsite/{{ commit.user.username }}/" > {{ commit.user.username }}</ a> </ span>
< span class = " pull-right id_replay" username = " {{ commit.user.username }}"
parent_id = " {{ commit.id }}" > < a> 回复</ a> </ span>
</ div>
< div>
{% if commit.commit_self_id %}
< p> @{{ commit.commit_self.user.username }}</ p>
< p> {{ commit.content }}</ p>
{% else %}
< p> {{ commit.content }}</ p>
{% endif %}
</ div>
</ li>
{% endfor %}
</ ul>
</ div>
< hr>
< div>
{% if request.user.is_authenticated %}
< p> 评论区</ p>
< textarea name = " " id = " commit" cols = " 80" rows = " 5" style =" resize : none" > </ textarea>
< p>
< button class = " btn btn-success" type = " button" id = " btn" > 评论</ button>
</ p>
{% else %}
< p> 请先< a href = " /login/" > 登录</ a> </ p>
{% endif %}
</ div>
</ div>
</ div>
</ div>
{% endblock %}
{% block js %}
< script>
let parent_id = ''
$ ( '.action' ) . click ( function ( ) {
let is_up = $ ( this ) . hasClass ( 'diggit' )
let span = $ ( this ) . children ( )
$. ajax ( {
url: '/diggit/' ,
method: 'post' ,
data: {
'is_up' : is_up,
'csrfmiddlewaretoken' : $ ( '[name="csrfmiddlewaretoken"]' ) . val ( ) ,
'article_id' : { { article. id } }
} ,
success: function ( data) {
$ ( '#digg_tips' ) . html ( data. msg)
if ( data. code === 100 ) {
$ ( span) . html ( Number ( $ ( span) . text ( ) ) + 1 )
}
}
} )
} )
$ ( '#btn' ) . click ( function ( ) {
let content = $ ( '#commit' ) . val ( )
if ( parent_id) {
let i = content. indexOf ( '\n' ) + 1
content = content. slice ( i)
}
$. ajax ( {
url: '/comment_content/' ,
method: 'post' ,
data: {
commit: content,
article_id: { { article. id } } ,
csrfmiddlewaretoken: $ ( '[name="csrfmiddlewaretoken"]' ) . val ( ) ,
parent_id: parent_id
} ,
success: function ( data) {
if ( data. code === 100 ) {
let username = data. username
let res_content = data. content
let parent_name = data. parent_name
let ss = ``
if ( parent_id) {
ss = `<li class="list-group-item">
<div>
<span><i class="fa fa-commenting-o fa-lg"></i> ${ username} </span>
</div>
<div>
<p>@ ${ parent_name} </p>
${ res_content}
</div>
</li>`
} else {
ss = `<li class="list-group-item">
<div>
<span><i class="fa fa-commenting-o fa-lg"></i> ${ username} </span>
</div>
<div>
${ res_content}
</div>
</li>`
}
$ ( '#commit' ) . val ( '' )
$ ( '.list-group' ) . append ( ss)
parent_id = ''
}
}
} )
} )
$ ( '.id_replay' ) . click ( function ( ) {
$ ( '#commit' ) . val ( '@' + $ ( this ) . attr ( 'username' ) + '\n' ) . focus ( )
parent_id = $ ( this ) . attr ( 'parent_id' )
} )
</ script>
{% endblock %}
15、update_head.html
{% extends 'backend/backbase.html' %}
{% block head %}
< form action = " " method = " post" enctype = " multipart/form-data" >
{% csrf_token %}
< div class = " form-group" >
< label for = " " > 原头像</ label>
< img src = " /media/{{ request.user.head }}" height = " 80" width = " 80" >
</ div>
< div class = " form-group" >
< label for = " id_myfile" > 新头像
< img src = " /static/img/default.png" alt = " " id = " id_img" height = " 80" width = " 80"
style =" margin-left : 10px" >
</ label>
< input type = " file" accept = " image/*" name = " myhead" id = " id_myfile" style =" display : none" >
</ div>
< div class = " text-center" >
< input type = " submit" value = " 修改" id = " id_submit" class = " btn btn-danger " > < span
class = " error text-danger" style =" margin-left : 10px" > </ span>
</ div>
</ form>
{% endblock %}
{% block script %}
< script>
$ ( '#id_myfile' ) . change ( function ( ) {
let filereader = new FileReader ( )
filereader. readAsDataURL ( this . files[ 0 ] )
filereader. onload = function ( ) {
$ ( '#id_img' ) . attr ( 'src' , filereader. result)
}
} )
</ script>
{% endblock %}
16、update_article.html
{% extends 'backend/backbase.html' %}
{% block content %}
< div>
< h4> 新增文章</ h4>
< form action = " " method = " post" >
{% csrf_token %}
< div class = " form-group" >
< label for = " " > 标题</ label>
< input type = " text" name = " name" class = " form-control" value = " {{ article.name }}" >
</ div>
< div class = " form-group" >
< label for = " " > 内容</ label>
< textarea name = " content" id = " editor_id" cols = " 80" rows = " 10"
class = " form-control" > {{ article.content }}</ textarea>
</ div>
< div>
个人分类:
{% for category in category_list %}
{{ article.category_id }}
< div class = " radio-inline" >
< label>
{% if article.category_id == category.id %}
< input type = " radio" name = " category" value = " {{ category.id }}" checked >
{% else %}
< input type = " radio" name = " category" value = " {{ category.id }}" >
{% endif %}
{{ category.name }}
</ label>
</ div>
{% endfor %}
</ div>
< div>
个人标签:
{% for tag in tag_list %}
< div class = " checkbox-inline" >
< label>
{% if tag in article.tag.all %}
< input type = " checkbox" name = " tag" value = " {{ tag.id }}" checked >
{% else %}
< input type = " checkbox" name = " tag" value = " {{ tag.id }}" >
{% endif %}
{{ tag.name }}
</ label>
</ div>
{% endfor %}
</ div>
< div class = " text-center" >
< input type = " submit" class = " btn btn-success" value = " 提交" >
</ div>
</ form>
</ div>
{% endblock %}
{% block script %}
< script charset = " utf-8" src = " /static/kindeditor/kindeditor-all.js" > </ script>
< script>
KindEditor. ready ( function ( K ) {
window. editor = K . create ( '#editor_id' , {
width: '100%' ,
height: '300px' ,
resizeType: 1 ,
uploadJson: '/upload_img/' ,
filePostName: 'myfile' ,
extraFileUploadParams: {
csrfmiddlewaretoken: '{{ csrf_token }}' ,
}
} ) ;
} ) ;
</ script>
{% endblock %}
17、backleft.html
< div class = " left_content col-md-3" >
< div class = " panel-group" id = " accordion" role = " tablist" aria-multiselectable = " true" >
< div class = " panel panel-default" >
< div class = " panel-heading" role = " tab" id = " headingOne" >
< h4 class = " panel-title" >
< a role = " button" data-toggle = " collapse" data-parent = " #accordion" href = " #collapseOne"
aria-expanded = " true" aria-controls = " collapseOne" >
操作
</ a>
</ h4>
</ div>
< div id = " collapseOne" class = " panel-collapse collapse in" role = " tabpanel"
aria-labelledby = " headingOne" >
< div class = " panel-body" >
< ul class = " nav" >
< li> < a href = " /add_article/" > 新增文章</ a> </ li>
< li> < a href = " /update_head/" > 修改头像</ a> </ li>
</ ul>
</ div>
</ div>
</ div>
< div class = " panel panel-default" >
< div class = " panel-heading" role = " tab" id = " headingTwo" >
< h4 class = " panel-title" >
< a class = " collapsed" role = " button" data-toggle = " collapse" data-parent = " #accordion"
href = " #collapseTwo" aria-expanded = " false" aria-controls = " collapseTwo" >
分类
</ a>
</ h4>
</ div>
< div id = " collapseTwo" class = " panel-collapse collapse" role = " tabpanel"
aria-labelledby = " headingTwo" >
< div class = " panel-body" >
< div class = " panel panel-info" >
< div class = " panel-heading" >
< h3 class = " panel-title" > 随笔分类</ h3>
</ div>
< div class = " panel-body" >
{% for category in res_category %}
< p>
< a href = " /blogsite/{{ name }}/category/{{ category.2 }}.html" > {{ category.0 }} ({{ category.1 }})</ a>
</ p>
{% endfor %}
</ div>
</ div>
</ div>
</ div>
</ div>
</ div>
</ div>
18、backend.html
{% extends 'backend/backbase.html' %}
{% block content %}
< div class = " container-fluid" >
< div class = " row" >
< table class = " table table-hover table-striped" >
< thead>
< tr>
< th> 标题</ th>
< th> 评论数</ th>
< th> 点赞数</ th>
< th> 操作</ th>
< th> 操作</ th>
</ tr>
</ thead>
< tbody>
{% for article in page_queryset %}
< tr>
< td>
< a href = " /{{ article.blog.user.username }}/article_detail/{{ article.pk }}.html" > {{ article.name|truncatechars:10 }}</ a>
</ td>
< td> {{ article.commit_num }}</ td>
< td> {{ article.up_num }}</ td>
< td> < a href = " /update_article/{{ article.pk }}/" > 编辑</ a> </ td>
< td> < a href = " /delete/{{ article.pk }}" > 删除</ a> </ td>
</ tr>
{% endfor %}
</ tbody>
</ table>
< div class = " text-center" > {{ page_obj.page_html|safe }}</ div>
</ div>
</ div>
{% endblock %}
19、backbase.html
<!DOCTYPE html>
< html lang = " en" >
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< title> {{ request.user.username }}的后台管理</ title>
{% load static %}
< script src = " {% static ' jquery-3.3.1/jquery-3.3.1.min.js' %}" > </ script>
< link href = " {% static ' bootstrap/css/bootstrap.min.css' %}" rel = " stylesheet" >
< link href = " {% static ' /font-awesome-4.7.0/font-awesome-4.7.0/css/font-awesome.css' %}" rel = " stylesheet" >
< script src = " {% static ' bootstrap/js/bootstrap.min.js' %}" > </ script>
</ head>
< body>
< div>
< div class = " header" >
< nav class = " navbar navbar-default navbar-inverse" >
< div class = " container-fluid" >
< div class = " navbar-header" >
< a class = " navbar-brand" href = " /backend/" > 后台管理</ a>
</ div>
< div class = " collapse navbar-collapse" id = " bs-example-navbar-collapse-1" >
< ul class = " nav navbar-nav" >
< li class = " active" > < a href = " /home/" > 首页 < span class = " sr-only" > (current)</ span> </ a> </ li>
</ ul>
</ div>
</ div>
</ nav>
</ div>
< div class = " container-fluid" >
< div class = " row" >
{% load blogsiteleft %}
{% backleft request %}
< div class = " right_content col-md-9" >
< div>
< ul class = " nav nav-tabs" role = " tablist" >
< li role = " presentation" class = " active" > < a href = " #home" aria-controls = " home" role = " tab"
data-toggle = " tab" > 文章</ a> </ li>
< li role = " presentation" > < a href = " #profile" aria-controls = " profile" role = " tab"
data-toggle = " tab" > 修改头像</ a>
</ li>
< li role = " presentation" > < a href = " #messages" aria-controls = " messages" role = " tab"
data-toggle = " tab" > 日志</ a>
</ li>
< li role = " presentation" > < a href = " #settings" aria-controls = " settings" role = " tab"
data-toggle = " tab" > 标签</ a>
</ li>
</ ul>
< div class = " tab-content" >
< div role = " tabpanel" class = " tab-pane active" id = " home" >
{% block content %}
{% endblock %}
</ div>
< div role = " tabpanel" class = " tab-pane" id = " profile" >
{% block head %}
{% endblock %}
</ div>
< div role = " tabpanel" class = " tab-pane" id = " messages" >
日志的内容
</ div>
< div role = " tabpanel" class = " tab-pane" id = " settings" >
标签的内容
</ div>
</ div>
</ div>
</ div>
</ div>
</ div>
</ div>
</ body>
{% block script %}
{% endblock %}
</ html>
20、add_article.html
{% extends 'backend/backbase.html' %}
{% block content %}
< div>
< h4> 新增文章</ h4>
< form action = " " method = " post" >
{% csrf_token %}
< div class = " form-group" >
< label for = " " > 标题</ label>
< input type = " text" name = " name" class = " form-control" >
</ div>
< div class = " form-group" >
< label for = " " > 内容</ label>
< textarea name = " content" id = " editor_id" cols = " 80" rows = " 10" class = " form-control" > </ textarea>
</ div>
< div>
个人分类:
{% for category in category_list %}
< div class = " radio-inline" >
< label>
< input type = " radio" name = " category" value = " {{ category.id }}" >
{{ category.name }}
</ label>
</ div>
{% endfor %}
</ div>
< div>
个人标签:
{% for tag in tag_list %}
< div class = " checkbox-inline" >
< label>
< input type = " checkbox" name = " tag" value = " {{ tag.id }}" >
{{ tag.name }}
</ label>
</ div>
{% endfor %}
</ div>
< div class = " text-center" >
< input type = " submit" class = " btn btn-success" value = " 提交" >
</ div>
</ form>
</ div>
{% endblock %}
{% block script %}
< script charset = " utf-8" src = " /static/kindeditor/kindeditor-all.js" > </ script>
< script>
KindEditor. ready ( function ( K ) {
window. editor = K . create ( '#editor_id' , {
width: '100%' ,
height: '300px' ,
resizeType: 1 ,
uploadJson: '/upload_img/' ,
filePostName: 'myfile' ,
extraFileUploadParams: {
csrfmiddlewaretoken: '{{ csrf_token }}' ,
}
} ) ;
} ) ;
</ script>
{% endblock %}