views.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. import datetime
  2. import logging
  3. # Create your views here.
  4. import os
  5. from django import forms
  6. from django.conf import settings
  7. from django.contrib.auth.decorators import login_required
  8. from django.http import HttpResponse
  9. from django.shortcuts import get_object_or_404
  10. from django.shortcuts import render
  11. from django.views.decorators.csrf import csrf_exempt
  12. from django.views.generic.detail import DetailView
  13. from django.views.generic.list import ListView
  14. from blog.models import Article, Category, Tag
  15. from comments.forms import CommentForm
  16. from website.utils import cache
  17. logger = logging.getLogger(__name__)
  18. class ArticleListView(ListView):
  19. # template_name属性用于指定使用哪个模板进行渲染
  20. template_name = 'blog/article_index.html'
  21. # context_object_name属性用于给上下文变量取名(在模板中使用该名字)
  22. context_object_name = 'article_list'
  23. # 页面类型,分类目录或标签列表等
  24. page_type = ''
  25. paginate_by = settings.PAGINATE_BY
  26. page_kwarg = 'page'
  27. def get_view_cache_key(self):
  28. return self.request.get['pages']
  29. @property
  30. def page_number(self):
  31. page_kwarg = self.page_kwarg
  32. page = self.kwargs.get(page_kwarg) or self.request.GET.get(page_kwarg) or 1
  33. return page
  34. def get_queryset_cache_key(self):
  35. """
  36. 子类重写.获得queryset的缓存key
  37. """
  38. raise NotImplementedError()
  39. def get_queryset_data(self):
  40. """
  41. 子类重写.获取queryset的数据
  42. """
  43. raise NotImplementedError()
  44. def get_queryset_from_cache(self, cache_key):
  45. # raise NotImplementedError()
  46. value = cache.get(cache_key)
  47. if value:
  48. logger.info('get view cache.key:{key}'.format(key=cache_key))
  49. return value
  50. else:
  51. article_list = self.get_queryset_data()
  52. cache.set(cache_key, article_list)
  53. logger.info('set view cache.key:{key}'.format(key=cache_key))
  54. return article_list
  55. def get_queryset(self):
  56. key = self.get_queryset_cache_key()
  57. value = self.get_queryset_from_cache(key)
  58. return value
  59. class IndexView(ArticleListView):
  60. def get_queryset_data(self):
  61. article_list = Article.objects.filter(type='a', status='p')
  62. return article_list
  63. def get_queryset_cache_key(self):
  64. cache_key = 'index_{page}'.format(page=self.page_number)
  65. return cache_key
  66. class ArticleDetailView(DetailView):
  67. template_name = 'blog/article_detail.html'
  68. model = Article
  69. pk_url_kwarg = 'article_id'
  70. context_object_name = "article"
  71. def get_object(self, queryset=None):
  72. obj = super(ArticleDetailView, self).get_object()
  73. obj.viewed()
  74. self.object = obj
  75. return obj
  76. def get_context_data(self, **kwargs):
  77. articleid = int(self.kwargs[self.pk_url_kwarg])
  78. comment_form = CommentForm()
  79. user = self.request.user
  80. if user.is_authenticated and not user.is_anonymous and user.email and user.username:
  81. comment_form.fields.update({
  82. 'email': forms.CharField(widget=forms.HiddenInput()),
  83. 'name': forms.CharField(widget=forms.HiddenInput()),
  84. })
  85. comment_form.fields["email"].initial = user.email
  86. comment_form.fields["name"].initial = user.username
  87. kwargs['form'] = comment_form
  88. article_comments = self.object.comment_list()
  89. kwargs['article_comments'] = article_comments
  90. kwargs['comment_count'] = len(article_comments) if article_comments else 0
  91. article_files = self.object.files_list()
  92. kwargs['article_files'] = article_files
  93. kwargs['files_count'] = len(article_files) if article_files else 0
  94. article_links = self.object.links_list()
  95. kwargs['article_links'] = article_links
  96. kwargs['links_count'] = len(article_links) if article_links else 0
  97. kwargs['next_article'] = self.object.next_article
  98. kwargs['prev_article'] = self.object.prev_article
  99. # FIXME 这里测试用
  100. # lurl = self.request.get_full_path()
  101. #
  102. # print(lurl)
  103. # print(self.request.get_raw_uri())
  104. # surl = get_surl(lurl)
  105. # print(surl)
  106. # qr = qrcode.QRCode(
  107. # version=1,
  108. # error_correction=qrcode.constants.ERROR_CORRECT_L,
  109. # box_size=10,
  110. # border=3,
  111. # )
  112. # qr.add_data('http://' + self.request.get_host() + surl)
  113. # qr.make(fit=True)
  114. #
  115. # img = qr.make_image(fill_color="black", back_color="white")
  116. # path = settings.BASE_DIR + '/media/qrcode/' + str(articleid) + '.png'
  117. # with open(path, 'wb') as f:
  118. # img.save(f)
  119. return super(ArticleDetailView, self).get_context_data(**kwargs)
  120. class CategoryDetailView(ArticleListView):
  121. page_type = "分类目录归档"
  122. def get_queryset_data(self):
  123. slug = self.kwargs['category_name']
  124. category = get_object_or_404(Category, slug=slug)
  125. categoryname = category.name
  126. self.categoryname = categoryname
  127. categorynames = list(map(lambda c: c.name, category.get_sub_categorys()))
  128. article_list = Article.objects.filter(category__name__in=categorynames, status='p')
  129. return article_list
  130. def get_queryset_cache_key(self):
  131. slug = self.kwargs['category_name']
  132. category = get_object_or_404(Category, slug=slug)
  133. categoryname = category.name
  134. self.categoryname = categoryname
  135. cache_key = 'category_list_{categoryname}_{page}'.format(categoryname=categoryname, page=self.page_number)
  136. return cache_key
  137. def get_context_data(self, **kwargs):
  138. categoryname = self.categoryname
  139. try:
  140. categoryname = categoryname.split('/')[-1]
  141. except:
  142. pass
  143. kwargs['page_type'] = CategoryDetailView.page_type
  144. kwargs['tag_name'] = categoryname
  145. return super(CategoryDetailView, self).get_context_data(**kwargs)
  146. class AuthorDetailView(ArticleListView):
  147. page_type = '作者文章归档'
  148. def get_queryset_cache_key(self):
  149. author_name = self.kwargs['author_name']
  150. cache_key = 'author_{author_name}_{page}'.format(author_name=author_name, page=self.page_number)
  151. return cache_key
  152. def get_queryset_data(self):
  153. author_name = self.kwargs['author_name']
  154. article_list = Article.objects.filter(author__username=author_name)
  155. return article_list
  156. def get_context_data(self, **kwargs):
  157. author_name = self.kwargs['author_name']
  158. kwargs['page_type'] = AuthorDetailView.page_type
  159. kwargs['tag_name'] = author_name
  160. return super(AuthorDetailView, self).get_context_data(**kwargs)
  161. class TagListView(ListView):
  162. template_name = ''
  163. context_object_name = 'tag_list'
  164. def get_queryset(self):
  165. tags_list = []
  166. tags = Tag.objects.all()
  167. for t in tags:
  168. t.article_set.count()
  169. class TagDetailView(ArticleListView):
  170. page_type = '分类标签归档'
  171. def get_queryset_data(self):
  172. slug = self.kwargs['tag_name']
  173. tag = get_object_or_404(Tag, slug=slug)
  174. tag_name = tag.name
  175. self.name = tag_name
  176. article_list = Article.objects.filter(tags__name=tag_name)
  177. return article_list
  178. def get_queryset_cache_key(self):
  179. slug = self.kwargs['tag_name']
  180. tag = get_object_or_404(Tag, slug=slug)
  181. tag_name = tag.name
  182. self.name = tag_name
  183. cache_key = 'tag_{tag_name}_{page}'.format(tag_name=tag_name, page=self.page_number)
  184. return cache_key
  185. def get_context_data(self, **kwargs):
  186. # tag_name = self.kwargs['tag_name']
  187. tag_name = self.name
  188. kwargs['page_type'] = TagDetailView.page_type
  189. kwargs['tag_name'] = tag_name
  190. return super(TagDetailView, self).get_context_data(**kwargs)
  191. class ArchivesView(ArticleListView):
  192. page_type = '文章归档'
  193. paginate_by = None
  194. page_kwarg = None
  195. template_name = 'blog/article_archives.html'
  196. def get_queryset_data(self):
  197. return Article.objects.filter(status='p').all()
  198. def get_queryset_cache_key(self):
  199. cache_key = 'archives'
  200. return cache_key
  201. @csrf_exempt
  202. def fileupload(request):
  203. if request.method == 'POST':
  204. response = []
  205. for filename in request.FILES:
  206. timestr = datetime.datetime.now().strftime('%Y/%m/%d')
  207. imgextensions = ['jpg', 'png', 'jpeg', 'bmp']
  208. fname = u''.join(str(filename))
  209. isimage = len([i for i in imgextensions if fname.find(i) >= 0]) > 0
  210. basepath = r'/var/www/resource/{type}/{timestr}'.format(
  211. type='files' if not isimage else 'image', timestr=timestr)
  212. if settings.TESTING:
  213. basepath = settings.BASE_DIR + '/uploads'
  214. url = 'https://xxxxxxxxxxxxxx/{type}/{timestr}/{filename}'.format(
  215. type='files' if not isimage else 'image', timestr=timestr, filename=filename)
  216. if not os.path.exists(basepath):
  217. os.makedirs(basepath)
  218. savepath = os.path.join(basepath, filename)
  219. with open(savepath, 'wb+') as wfile:
  220. for chunk in request.FILES[filename].chunks():
  221. wfile.write(chunk)
  222. if isimage:
  223. from PIL import Image
  224. image = Image.open(savepath)
  225. image.save(savepath, quality=20, optimize=True)
  226. response.append(url)
  227. return HttpResponse(response)
  228. else:
  229. return HttpResponse("only for post")
  230. @login_required
  231. def refresh_memcache(request):
  232. try:
  233. if request.user.is_superuser:
  234. from website.utils import cache
  235. if cache and cache is not None:
  236. cache.clear()
  237. return HttpResponse("ok")
  238. else:
  239. from django.http import HttpResponseForbidden
  240. return HttpResponseForbidden()
  241. except Exception as e:
  242. logger.error(e)
  243. return HttpResponse(e)
  244. def page_not_found_view(request, exception, template_name='blog/error_page.html'):
  245. if exception:
  246. logger.error(exception)
  247. url = request.get_full_path()
  248. return render(request, template_name,
  249. {'message': '哎呀,您访问的地址 ' + url + ' 是一个未知的地方。请点击首页看看别的?', 'statuscode': '404'}, status=404)
  250. def server_error_view(request, template_name='blog/error_page.html'):
  251. return render(request, template_name,
  252. {'message': '哎呀,出错了,我已经收集到了错误信息,之后会抓紧抢修,请点击首页看看别的?', 'statuscode': '500'}, status=500)
  253. def permission_denied_view(request, exception, template_name='blog/error_page.html'):
  254. if exception:
  255. logger.error(exception)
  256. return render(request, template_name,
  257. {'message': '哎呀,您没有权限访问此页面,请点击首页看看别的?', 'statuscode': '403'}, status=403)