@ -1,80 +1,64 @@
# bjy: 导入日志、操作系统和UUID模块
import logging
import logging
import os
import os
import uuid
import uuid
# bjy: 从Django中导入设置、分页器、HTTP响应、快捷函数、静态文件、时区、国际化、CSRF豁免和基于类的视图
from django . conf import settings
from django . conf import settings
from django . contrib . auth . decorators import login_required
from django . core . paginator import Paginator
from django . core . paginator import Paginator
from django . http import HttpResponse , HttpResponseForbidden , JsonResponse
from django . http import HttpResponse , HttpResponseForbidden
from django . shortcuts import get_object_or_404
from django . shortcuts import get_object_or_404
from django . shortcuts import render
from django . shortcuts import render
from django . templatetags . static import static
from django . templatetags . static import static
from django . utils import timezone
from django . utils import timezone
from django . utils . decorators import method_decorator
from django . utils . translation import gettext_lazy as _
from django . utils . translation import gettext_lazy as _
from django . views import View
from django . views . decorators . csrf import csrf_exempt
from django . views . decorators . csrf import csrf_exempt
from django . views . generic . detail import DetailView
from django . views . generic . detail import DetailView
from django . views . generic . list import ListView
from django . views . generic . list import ListView
# bjy: 从Haystack中导入搜索视图
from haystack . views import SearchView
from haystack . views import SearchView
# bjy: 从项目中导入博客模型、评论表单、插件管理器和工具函数
from blog . models import Article , Category , LinkShowType , Links , Tag
from blog . models import Article , Category , LinkShowType , Links , Tag
from comments . forms import CommentForm
from comments . forms import CommentForm
from djangoblog . plugin_manage import hooks
from djangoblog . plugin_manage import hooks
from djangoblog . plugin_manage . hook_constants import ARTICLE_CONTENT_HOOK_NAME
from djangoblog . plugin_manage . hook_constants import ARTICLE_CONTENT_HOOK_NAME
from djangoblog . utils import cache , get_blog_setting , get_sha256
from djangoblog . utils import cache , get_blog_setting , get_sha256
# bjy: 获取一个名为__name__的logger实例, 用于记录日志
logger = logging . getLogger ( __name__ )
logger = logging . getLogger ( __name__ )
# bjy: 定义一个基于类的文章列表视图,作为其他列表视图的基类
class ArticleListView ( ListView ) :
class ArticleListView ( ListView ) :
# bjy: 指定渲染的模板文件
# template_name属性用于指定使用哪个模板进行渲染
template_name = ' blog/article_index.html '
template_name = ' blog/article_index.html '
# bjy: 指定在模板中使用的上下文变量名
# context_object_name属性用于给上下文变量取名( 在模板中使用该名字)
context_object_name = ' article_list '
context_object_name = ' article_list '
# bjy: 页面类型,用于在模板中显示不同的标题
# 页面类型,分类目录或标签列表等
page_type = ' '
page_type = ' '
# bjy: 每页显示的文章数量,从设置中获取
paginate_by = settings . PAGINATE_BY
paginate_by = settings . PAGINATE_BY
# bjy: URL中分页参数的名称
page_kwarg = ' page '
page_kwarg = ' page '
# bjy: 友情链接的显示类型,默认为列表页
link_type = LinkShowType . L
link_type = LinkShowType . L
# bjy: 获取视图的缓存键(此方法未使用)
def get_view_cache_key ( self ) :
def get_view_cache_key ( self ) :
return self . request . get [ ' pages ' ]
return self . request . get [ ' pages ' ]
# bjy: 属性,用于获取当前页码
@property
@property
def page_number ( self ) :
def page_number ( self ) :
page_kwarg = self . page_kwarg
page_kwarg = self . page_kwarg
# bjy: 从URL参数或GET参数中获取页码, 默认为1
page = self . kwargs . get (
page = self . kwargs . get (
page_kwarg ) or self . request . GET . get ( page_kwarg ) or 1
page_kwarg ) or self . request . GET . get ( page_kwarg ) or 1
return page
return page
# bjy: 抽象方法, 要求子类实现, 用于获取queryset的缓存键
def get_queryset_cache_key ( self ) :
def get_queryset_cache_key ( self ) :
"""
"""
子类重写 . 获得queryset的缓存key
子类重写 . 获得queryset的缓存key
"""
"""
raise NotImplementedError ( )
raise NotImplementedError ( )
# bjy: 抽象方法,要求子类实现,用于获取实际的数据集
def get_queryset_data ( self ) :
def get_queryset_data ( self ) :
"""
"""
子类重写 . 获取queryset的数据
子类重写 . 获取queryset的数据
"""
"""
raise NotImplementedError ( )
raise NotImplementedError ( )
# bjy: 从缓存中获取数据集,如果缓存不存在则查询数据库并存入缓存
def get_queryset_from_cache ( self , cache_key ) :
def get_queryset_from_cache ( self , cache_key ) :
'''
'''
缓存页面数据
缓存页面数据
@ -86,13 +70,11 @@ class ArticleListView(ListView):
logger . info ( ' get view cache.key: {key} ' . format ( key = cache_key ) )
logger . info ( ' get view cache.key: {key} ' . format ( key = cache_key ) )
return value
return value
else :
else :
# bjy: 调用子类实现的get_queryset_data方法获取数据
article_list = self . get_queryset_data ( )
article_list = self . get_queryset_data ( )
cache . set ( cache_key , article_list )
cache . set ( cache_key , article_list )
logger . info ( ' set view cache.key: {key} ' . format ( key = cache_key ) )
logger . info ( ' set view cache.key: {key} ' . format ( key = cache_key ) )
return article_list
return article_list
# bjy: 重写父类方法, 从缓存中获取queryset
def get_queryset ( self ) :
def get_queryset ( self ) :
'''
'''
重写默认 , 从缓存获取数据
重写默认 , 从缓存获取数据
@ -102,13 +84,11 @@ class ArticleListView(ListView):
value = self . get_queryset_from_cache ( key )
value = self . get_queryset_from_cache ( key )
return value
return value
# bjy: 重写父类方法,向上下文中添加链接类型
def get_context_data ( self , * * kwargs ) :
def get_context_data ( self , * * kwargs ) :
kwargs [ ' linktype ' ] = self . link_type
kwargs [ ' linktype ' ] = self . link_type
return super ( ArticleListView , self ) . get_context_data ( * * kwargs )
return super ( ArticleListView , self ) . get_context_data ( * * kwargs )
# bjy: 首页视图, 继承自ArticleListView
class IndexView ( ArticleListView ) :
class IndexView ( ArticleListView ) :
'''
'''
首页
首页
@ -116,18 +96,15 @@ class IndexView(ArticleListView):
# 友情链接类型
# 友情链接类型
link_type = LinkShowType . I
link_type = LinkShowType . I
# bjy: 实现父类的抽象方法,获取首页的文章数据
def get_queryset_data ( self ) :
def get_queryset_data ( self ) :
article_list = Article . objects . filter ( type = ' a ' , status = ' p ' )
article_list = Article . objects . filter ( type = ' a ' , status = ' p ' )
return article_list
return article_list
# bjy: 实现父类的抽象方法,生成首页的缓存键
def get_queryset_cache_key ( self ) :
def get_queryset_cache_key ( self ) :
cache_key = ' index_ {page} ' . format ( page = self . page_number )
cache_key = ' index_ {page} ' . format ( page = self . page_number )
return cache_key
return cache_key
# bjy: 文章详情页视图
class ArticleDetailView ( DetailView ) :
class ArticleDetailView ( DetailView ) :
'''
'''
文章详情页面
文章详情页面
@ -137,21 +114,14 @@ class ArticleDetailView(DetailView):
pk_url_kwarg = ' article_id '
pk_url_kwarg = ' article_id '
context_object_name = " article "
context_object_name = " article "
# bjy: 重写父类方法,向上下文中添加额外的数据
def get_context_data ( self , * * kwargs ) :
def get_context_data ( self , * * kwargs ) :
# bjy: 创建评论表单实例
comment_form = CommentForm ( )
comment_form = CommentForm ( )
# bjy: 获取文章的所有评论
article_comments = self . object . comment_list ( )
article_comments = self . object . comment_list ( )
# bjy: 筛选出父评论(顶级评论)
parent_comments = article_comments . filter ( parent_comment = None )
parent_comments = article_comments . filter ( parent_comment = None )
# bjy: 获取博客设置
blog_setting = get_blog_setting ( )
blog_setting = get_blog_setting ( )
# bjy: 对父评论进行分页
paginator = Paginator ( parent_comments , blog_setting . article_comment_count )
paginator = Paginator ( parent_comments , blog_setting . article_comment_count )
# bjy: 从GET参数中获取评论页码
page = self . request . GET . get ( ' comment_page ' , ' 1 ' )
page = self . request . GET . get ( ' comment_page ' , ' 1 ' )
# bjy: 校验页码是否为有效数字
if not page . isnumeric ( ) :
if not page . isnumeric ( ) :
page = 1
page = 1
else :
else :
@ -161,68 +131,55 @@ class ArticleDetailView(DetailView):
if page > paginator . num_pages :
if page > paginator . num_pages :
page = paginator . num_pages
page = paginator . num_pages
# bjy: 获取当前页的评论对象
p_comments = paginator . page ( page )
p_comments = paginator . page ( page )
# bjy: 获取下一页和上一页的页码
next_page = p_comments . next_page_number ( ) if p_comments . has_next ( ) else None
next_page = p_comments . next_page_number ( ) if p_comments . has_next ( ) else None
prev_page = p_comments . previous_page_number ( ) if p_comments . has_previous ( ) else None
prev_page = p_comments . previous_page_number ( ) if p_comments . has_previous ( ) else None
# bjy: 如果存在下一页, 则构建下一页的URL
if next_page :
if next_page :
kwargs [
kwargs [
' comment_next_page_url ' ] = self . object . get_absolute_url ( ) + f ' ?comment_page= { next_page } #commentlist-container '
' comment_next_page_url ' ] = self . object . get_absolute_url ( ) + f ' ?comment_page= { next_page } #commentlist-container '
# bjy: 如果存在上一页, 则构建上一页的URL
if prev_page :
if prev_page :
kwargs [
kwargs [
' comment_prev_page_url ' ] = self . object . get_absolute_url ( ) + f ' ?comment_page= { prev_page } #commentlist-container '
' comment_prev_page_url ' ] = self . object . get_absolute_url ( ) + f ' ?comment_page= { prev_page } #commentlist-container '
# bjy: 将评论表单和评论数据添加到上下文
kwargs [ ' form ' ] = comment_form
kwargs [ ' form ' ] = comment_form
kwargs [ ' article_comments ' ] = article_comments
kwargs [ ' article_comments ' ] = article_comments
kwargs [ ' p_comments ' ] = p_comments
kwargs [ ' p_comments ' ] = p_comments
kwargs [ ' comment_count ' ] = len (
kwargs [ ' comment_count ' ] = len (
article_comments ) if article_comments else 0
article_comments ) if article_comments else 0
# bjy: 添加上一篇和下一篇文章
kwargs [ ' next_article ' ] = self . object . next_article
kwargs [ ' next_article ' ] = self . object . next_article
kwargs [ ' prev_article ' ] = self . object . prev_article
kwargs [ ' prev_article ' ] = self . object . prev_article
# bjy: 调用父类方法获取基础上下文
context = super ( ArticleDetailView , self ) . get_context_data ( * * kwargs )
context = super ( ArticleDetailView , self ) . get_context_data ( * * kwargs )
article = self . object
article = self . object
# bjy: 触发文章详情加载钩子,让插件可以添加额外的上下文数据
# 触发文章详情加载钩子,让插件可以添加额外的上下文数据
from djangoblog . plugin_manage . hook_constants import ARTICLE_DETAIL_LOAD
from djangoblog . plugin_manage . hook_constants import ARTICLE_DETAIL_LOAD
hooks . run_action ( ARTICLE_DETAIL_LOAD , article = article , context = context , request = self . request )
hooks . run_action ( ARTICLE_DETAIL_LOAD , article = article , context = context , request = self . request )
# bjy: Action Hook, 通知插件"文章详情已获取"
# Action Hook, 通知插件"文章详情已获取"
hooks . run_action ( ' after_article_body_get ' , article = article , request = self . request )
hooks . run_action ( ' after_article_body_get ' , article = article , request = self . request )
return context
return context
# bjy: 分类详情页视图
class CategoryDetailView ( ArticleListView ) :
class CategoryDetailView ( ArticleListView ) :
'''
'''
分类目录列表
分类目录列表
'''
'''
page_type = " 分类目录归档 "
page_type = " 分类目录归档 "
# bjy: 实现父类的抽象方法,获取分类下的文章数据
def get_queryset_data ( self ) :
def get_queryset_data ( self ) :
slug = self . kwargs [ ' category_name ' ]
slug = self . kwargs [ ' category_name ' ]
# bjy: 根据slug获取分类对象, 如果不存在则返回404
category = get_object_or_404 ( Category , slug = slug )
category = get_object_or_404 ( Category , slug = slug )
categoryname = category . name
categoryname = category . name
self . categoryname = categoryname
self . categoryname = categoryname
# bjy: 获取该分类及其所有子分类的名称列表
categorynames = list (
categorynames = list (
map ( lambda c : c . name , category . get_sub_categorys ( ) ) )
map ( lambda c : c . name , category . get_sub_categorys ( ) ) )
# bjy: 筛选出属于这些分类的所有已发布文章
article_list = Article . objects . filter (
article_list = Article . objects . filter (
category__name__in = categorynames , status = ' p ' )
category__name__in = categorynames , status = ' p ' )
return article_list
return article_list
# bjy: 实现父类的抽象方法,生成分类页的缓存键
def get_queryset_cache_key ( self ) :
def get_queryset_cache_key ( self ) :
slug = self . kwargs [ ' category_name ' ]
slug = self . kwargs [ ' category_name ' ]
category = get_object_or_404 ( Category , slug = slug )
category = get_object_or_404 ( Category , slug = slug )
@ -232,12 +189,10 @@ class CategoryDetailView(ArticleListView):
categoryname = categoryname , page = self . page_number )
categoryname = categoryname , page = self . page_number )
return cache_key
return cache_key
# bjy: 重写父类方法,向上下文中添加分类名称
def get_context_data ( self , * * kwargs ) :
def get_context_data ( self , * * kwargs ) :
categoryname = self . categoryname
categoryname = self . categoryname
try :
try :
# bjy: 处理多级分类的情况,只取最后一部分
categoryname = categoryname . split ( ' / ' ) [ - 1 ]
categoryname = categoryname . split ( ' / ' ) [ - 1 ]
except BaseException :
except BaseException :
pass
pass
@ -246,14 +201,12 @@ class CategoryDetailView(ArticleListView):
return super ( CategoryDetailView , self ) . get_context_data ( * * kwargs )
return super ( CategoryDetailView , self ) . get_context_data ( * * kwargs )
# bjy: 作者详情页视图
class AuthorDetailView ( ArticleListView ) :
class AuthorDetailView ( ArticleListView ) :
'''
'''
作者详情页
作者详情页
'''
'''
page_type = ' 作者文章归档 '
page_type = ' 作者文章归档 '
# bjy: 实现父类的抽象方法,生成作者页的缓存键
def get_queryset_cache_key ( self ) :
def get_queryset_cache_key ( self ) :
from uuslug import slugify
from uuslug import slugify
author_name = slugify ( self . kwargs [ ' author_name ' ] )
author_name = slugify ( self . kwargs [ ' author_name ' ] )
@ -261,14 +214,12 @@ class AuthorDetailView(ArticleListView):
author_name = author_name , page = self . page_number )
author_name = author_name , page = self . page_number )
return cache_key
return cache_key
# bjy: 实现父类的抽象方法,获取作者的文章数据
def get_queryset_data ( self ) :
def get_queryset_data ( self ) :
author_name = self . kwargs [ ' author_name ' ]
author_name = self . kwargs [ ' author_name ' ]
article_list = Article . objects . filter (
article_list = Article . objects . filter (
author__username = author_name , type = ' a ' , status = ' p ' )
author__username = author_name , type = ' a ' , status = ' p ' )
return article_list
return article_list
# bjy: 重写父类方法,向上下文中添加作者名称
def get_context_data ( self , * * kwargs ) :
def get_context_data ( self , * * kwargs ) :
author_name = self . kwargs [ ' author_name ' ]
author_name = self . kwargs [ ' author_name ' ]
kwargs [ ' page_type ' ] = AuthorDetailView . page_type
kwargs [ ' page_type ' ] = AuthorDetailView . page_type
@ -276,14 +227,12 @@ class AuthorDetailView(ArticleListView):
return super ( AuthorDetailView , self ) . get_context_data ( * * kwargs )
return super ( AuthorDetailView , self ) . get_context_data ( * * kwargs )
# bjy: 标签详情页视图
class TagDetailView ( ArticleListView ) :
class TagDetailView ( ArticleListView ) :
'''
'''
标签列表页面
标签列表页面
'''
'''
page_type = ' 分类标签归档 '
page_type = ' 分类标签归档 '
# bjy: 实现父类的抽象方法,获取标签下的文章数据
def get_queryset_data ( self ) :
def get_queryset_data ( self ) :
slug = self . kwargs [ ' tag_name ' ]
slug = self . kwargs [ ' tag_name ' ]
tag = get_object_or_404 ( Tag , slug = slug )
tag = get_object_or_404 ( Tag , slug = slug )
@ -293,7 +242,6 @@ class TagDetailView(ArticleListView):
tags__name = tag_name , type = ' a ' , status = ' p ' )
tags__name = tag_name , type = ' a ' , status = ' p ' )
return article_list
return article_list
# bjy: 实现父类的抽象方法,生成标签页的缓存键
def get_queryset_cache_key ( self ) :
def get_queryset_cache_key ( self ) :
slug = self . kwargs [ ' tag_name ' ]
slug = self . kwargs [ ' tag_name ' ]
tag = get_object_or_404 ( Tag , slug = slug )
tag = get_object_or_404 ( Tag , slug = slug )
@ -303,7 +251,6 @@ class TagDetailView(ArticleListView):
tag_name = tag_name , page = self . page_number )
tag_name = tag_name , page = self . page_number )
return cache_key
return cache_key
# bjy: 重写父类方法,向上下文中添加标签名称
def get_context_data ( self , * * kwargs ) :
def get_context_data ( self , * * kwargs ) :
# tag_name = self.kwargs['tag_name']
# tag_name = self.kwargs['tag_name']
tag_name = self . name
tag_name = self . name
@ -312,40 +259,32 @@ class TagDetailView(ArticleListView):
return super ( TagDetailView , self ) . get_context_data ( * * kwargs )
return super ( TagDetailView , self ) . get_context_data ( * * kwargs )
# bjy: 文章归档页视图
class ArchivesView ( ArticleListView ) :
class ArchivesView ( ArticleListView ) :
'''
'''
文章归档页面
文章归档页面
'''
'''
page_type = ' 文章归档 '
page_type = ' 文章归档 '
# bjy: 归档页不分页
paginate_by = None
paginate_by = None
page_kwarg = None
page_kwarg = None
template_name = ' blog/article_archives.html '
template_name = ' blog/article_archives.html '
# bjy: 实现父类的抽象方法,获取所有已发布文章
def get_queryset_data ( self ) :
def get_queryset_data ( self ) :
return Article . objects . filter ( status = ' p ' ) . all ( )
return Article . objects . filter ( status = ' p ' ) . all ( )
# bjy: 实现父类的抽象方法,生成归档页的缓存键
def get_queryset_cache_key ( self ) :
def get_queryset_cache_key ( self ) :
cache_key = ' archives '
cache_key = ' archives '
return cache_key
return cache_key
# bjy: 友情链接页视图
class LinkListView ( ListView ) :
class LinkListView ( ListView ) :
model = Links
model = Links
template_name = ' blog/links_list.html '
template_name = ' blog/links_list.html '
# bjy: 重写queryset, 只获取已启用的链接
def get_queryset ( self ) :
def get_queryset ( self ) :
return Links . objects . filter ( is_enable = True )
return Links . objects . filter ( is_enable = True )
# bjy: 自定义的Elasticsearch搜索视图
class EsSearchView ( SearchView ) :
class EsSearchView ( SearchView ) :
# bjy: 重写get_context方法, 自定义搜索结果的上下文
def get_context ( self ) :
def get_context ( self ) :
paginator , page = self . build_page ( )
paginator , page = self . build_page ( )
context = {
context = {
@ -355,7 +294,6 @@ class EsSearchView(SearchView):
" paginator " : paginator ,
" paginator " : paginator ,
" suggestion " : None ,
" suggestion " : None ,
}
}
# bjy: 如果启用了拼写建议,则添加到上下文
if hasattr ( self . results , " query " ) and self . results . query . backend . include_spelling :
if hasattr ( self . results , " query " ) and self . results . query . backend . include_spelling :
context [ " suggestion " ] = self . results . query . get_spelling_suggestion ( )
context [ " suggestion " ] = self . results . query . get_spelling_suggestion ( )
context . update ( self . extra_context ( ) )
context . update ( self . extra_context ( ) )
@ -363,44 +301,6 @@ class EsSearchView(SearchView):
return context
return context
class LikeArticle ( View ) :
"""
处理文章点赞和取消点赞
"""
@method_decorator ( login_required ) # 确保只有登录用户才能点赞
def post ( self , request ) :
try :
user = request . user
article_id = request . POST . get ( ' article_id ' ) # 获取文章ID
article = Article . objects . get ( id = article_id ) # 获取文章对象
# 检查当前用户是否已经为这篇文章点过赞
if article . users_like . filter ( id = user . id ) . exists ( ) :
# 如果点过赞,则取消点赞 (从多对多关系中移除)
article . users_like . remove ( user )
action_type = 0 # 0代表取消点赞
else :
# 如果没点过赞,则添加点赞 (添加到多对多关系)
article . users_like . add ( user )
action_type = 1 # 1代表点赞
# 获取更新后的点赞总数
like_count = article . users_like . count ( )
# 返回JSON数据给前端
return JsonResponse ( {
' state ' : 200 ,
' type ' : action_type ,
' like_sum ' : like_count
} )
except Article . DoesNotExist :
return JsonResponse ( { ' state ' : 400 , ' data ' : ' 文章不存在 ' } )
except Exception as e :
return JsonResponse ( { ' state ' : 500 , ' data ' : f ' 服务器错误: { e } ' } )
# bjy: 文件上传视图, 使用csrf_exempt豁免CSRF验证
@csrf_exempt
@csrf_exempt
def fileupload ( request ) :
def fileupload ( request ) :
"""
"""
@ -409,52 +309,38 @@ def fileupload(request):
: return :
: return :
"""
"""
if request . method == ' POST ' :
if request . method == ' POST ' :
# bjy: 从GET参数中获取签名
sign = request . GET . get ( ' sign ' , None )
sign = request . GET . get ( ' sign ' , None )
if not sign :
if not sign :
return HttpResponseForbidden ( )
return HttpResponseForbidden ( )
# bjy: 验证签名是否正确
if not sign == get_sha256 ( get_sha256 ( settings . SECRET_KEY ) ) :
if not sign == get_sha256 ( get_sha256 ( settings . SECRET_KEY ) ) :
return HttpResponseForbidden ( )
return HttpResponseForbidden ( )
response = [ ]
response = [ ]
# bjy: 遍历所有上传的文件
for filename in request . FILES :
for filename in request . FILES :
# bjy: 按年/月/日创建目录
timestr = timezone . now ( ) . strftime ( ' % Y/ % m/ %d ' )
timestr = timezone . now ( ) . strftime ( ' % Y/ % m/ %d ' )
imgextensions = [ ' jpg ' , ' png ' , ' jpeg ' , ' bmp ' ]
imgextensions = [ ' jpg ' , ' png ' , ' jpeg ' , ' bmp ' ]
fname = u ' ' . join ( str ( filename ) )
fname = u ' ' . join ( str ( filename ) )
# bjy: 判断文件是否为图片
isimage = len ( [ i for i in imgextensions if fname . find ( i ) > = 0 ] ) > 0
isimage = len ( [ i for i in imgextensions if fname . find ( i ) > = 0 ] ) > 0
base_dir = os . path . join ( settings . STATICFILES , " files " if not isimage else " image " , timestr )
base_dir = os . path . join ( settings . STATICFILES , " files " if not isimage else " image " , timestr )
# bjy: 如果目录不存在则创建
if not os . path . exists ( base_dir ) :
if not os . path . exists ( base_dir ) :
os . makedirs ( base_dir )
os . makedirs ( base_dir )
# bjy: 生成唯一的文件名并拼接保存路径
savepath = os . path . normpath ( os . path . join ( base_dir , f " { uuid . uuid4 ( ) . hex } { os . path . splitext ( filename ) [ - 1 ] } " ) )
savepath = os . path . normpath ( os . path . join ( base_dir , f " { uuid . uuid4 ( ) . hex } { os . path . splitext ( filename ) [ - 1 ] } " ) )
# bjy: 安全检查,防止路径遍历攻击
if not savepath . startswith ( base_dir ) :
if not savepath . startswith ( base_dir ) :
return HttpResponse ( " only for post " )
return HttpResponse ( " only for post " )
# bjy: 将文件内容写入磁盘
with open ( savepath , ' wb+ ' ) as wfile :
with open ( savepath , ' wb+ ' ) as wfile :
for chunk in request . FILES [ filename ] . chunks ( ) :
for chunk in request . FILES [ filename ] . chunks ( ) :
wfile . write ( chunk )
wfile . write ( chunk )
# bjy: 如果是图片,则进行压缩优化
if isimage :
if isimage :
from PIL import Image
from PIL import Image
image = Image . open ( savepath )
image = Image . open ( savepath )
image . save ( savepath , quality = 20 , optimize = True )
image . save ( savepath , quality = 20 , optimize = True )
# bjy: 生成文件的静态URL
url = static ( savepath )
url = static ( savepath )
response . append ( url )
response . append ( url )
# bjy: 返回包含所有文件URL的响应
return HttpResponse ( response )
return HttpResponse ( response )
else :
else :
# bjy: 非POST请求返回错误信息
return HttpResponse ( " only for post " )
return HttpResponse ( " only for post " )
# bjy: 自定义404错误处理视图
def page_not_found_view (
def page_not_found_view (
request ,
request ,
exception ,
exception ,
@ -469,7 +355,6 @@ def page_not_found_view(
status = 404 )
status = 404 )
# bjy: 自定义500服务器错误处理视图
def server_error_view ( request , template_name = ' blog/error_page.html ' ) :
def server_error_view ( request , template_name = ' blog/error_page.html ' ) :
return render ( request ,
return render ( request ,
template_name ,
template_name ,
@ -478,7 +363,6 @@ def server_error_view(request, template_name='blog/error_page.html'):
status = 500 )
status = 500 )
# bjy: 自定义403权限拒绝错误处理视图
def permission_denied_view (
def permission_denied_view (
request ,
request ,
exception ,
exception ,
@ -491,7 +375,6 @@ def permission_denied_view(
' statuscode ' : ' 403 ' } , status = 403 )
' statuscode ' : ' 403 ' } , status = 403 )
# bjy: 清除缓存的视图
def clean_cache_view ( request ) :
def clean_cache_view ( request ) :
cache . clear ( )
cache . clear ( )
return HttpResponse ( ' ok ' )
return HttpResponse ( ' ok ' )