article.py 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429
  1. import json
  2. from datetime import datetime, timedelta
  3. from django.contrib.auth.decorators import login_required
  4. from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage
  5. from django.http import JsonResponse, HttpResponseRedirect
  6. from django.shortcuts import render, redirect
  7. from django.urls import reverse
  8. from django.utils import timezone
  9. import blog
  10. from blog import models
  11. from system.error.ServerException import ServerException
  12. @login_required(login_url='/login')
  13. def article(request):
  14. page = request.GET.get('page')
  15. search_title = request.GET.get('search_title')
  16. search_content = request.GET.get('search_content')
  17. search_category = request.GET.get('search_category')
  18. if page is None:
  19. page = 0
  20. articles = blog.controller.article.get_article(is_paginator=True, page=int(page), search_title=search_title,
  21. search_content=search_content, search_category=search_category,draft=False)
  22. return render(request, 'management/article/article.html', context={'articles': articles})
  23. @login_required(login_url='/login')
  24. def draft(request):
  25. page = request.GET.get('page')
  26. search_title = request.GET.get('search_title')
  27. search_content = request.GET.get('search_content')
  28. search_category = request.GET.get('search_category')
  29. if page is None:
  30. page = 0
  31. articles = blog.controller.article.get_article(is_paginator=True, page=int(page), search_title=search_title,
  32. search_content=search_content, search_category=search_category,
  33. draft=True)
  34. return render(request, 'management/article/draft.html', context={'articles': articles})
  35. @login_required(login_url='/login')
  36. def set_status(request,pk):
  37. article = models.Article.objects.filter(id=int(pk)).first()
  38. if article is not None:
  39. if article.status == 0:
  40. article.status = 1
  41. else:
  42. article.status = 0
  43. article.save()
  44. # 把所有 GET 参数重新编码(可能包含 page,也可能不包含)
  45. query = request.GET.urlencode() # e.g. "page=2&foo=bar" 或者 ""
  46. # 构造基础列表页 URL
  47. base = '/management/article' # 或者直接 '/management/article'
  48. # 如果有任何查询参数,就拼接 ?xxx,否则直接跳
  49. redirect_url = f'{base}?{query}' if query else base
  50. return redirect(redirect_url)
  51. @login_required(login_url='/login')
  52. def cancel_show_index(request, pk):
  53. article = models.Article.objects.get(id=int(pk))
  54. article.is_top = False
  55. article.save()
  56. return HttpResponseRedirect('/') # 跳转到主界面
  57. @login_required(login_url='/login')
  58. def show_show_index(request, pk):
  59. article = models.Article.objects.get(id=int(pk))
  60. article.is_top = True
  61. article.save()
  62. return HttpResponseRedirect('/') # 跳转到主界面
  63. def new(request):
  64. return render(request, 'management/article/new_article.html')
  65. def show_article(request, pk):
  66. article = models.Article.objects.filter(id=int(pk)).values('id', 'title', 'intro', 'category',
  67. 'user', 'created_time', 'type',
  68. 'cover__file_net_path',
  69. 'music__file_net_path', 'status',
  70. 'category__name',
  71. 'user__first_name', 'user_id',
  72. 'user__last_name', 'markdown_text', 'is_top',
  73. 'html_text').first()
  74. comments = models.Comment.objects.filter(article_id=article['id'])
  75. # request.session['msg'] = ''
  76. from blog.views import get_record_and_tags
  77. result = get_record_and_tags()
  78. return render(request, 'blog.html', context={'article': article, 'records': result['records'],
  79. 'tags': result['tags'], 'comments': comments})
  80. @login_required(login_url='/')
  81. def to_edit(request, pk):
  82. article = models.Article.objects.filter(id=int(pk)).values('id', 'title', 'intro', 'category',
  83. 'user', 'created_time', 'type',
  84. 'cover__file_net_path',
  85. 'music__file_net_path', 'status',
  86. 'category__name',
  87. 'user__first_name', 'user_id',
  88. 'user__last_name', 'markdown_text', 'html_text',
  89. 'is_top').first()
  90. tags = models.Tags.objects.raw(
  91. 'select * from blog_tags left join blog_article_tags bat on blog_tags.id = bat.tags_id where bat.article_id = {0}'.format(
  92. int(pk)))
  93. tags_str = []
  94. for tag in tags:
  95. tags_str.append(tag.name)
  96. return render(request, 'management/article/edit_article.html',
  97. context={'article': article, 'tags': ','.join(tags_str)})
  98. @login_required(login_url='/')
  99. def edit_article(request):
  100. if request.method == 'POST':
  101. title = request.POST['title']
  102. intro = request.POST['intro']
  103. category = request.POST['category']
  104. html_text = request.POST['html']
  105. markdown_text = request.POST['markdown']
  106. type_ = request.POST['type']
  107. status = request.POST['status']
  108. tags = request.POST['tags']
  109. pk = request.POST['pk']
  110. is_top = request.POST['is_top']
  111. category_obj = models.Category.objects.get(id=category)
  112. article_obj = models.Article.objects.get(id=int(pk))
  113. tags_id = []
  114. for tag in str(tags).split(','):
  115. if tag == '':
  116. break
  117. else:
  118. tag_obj = models.Tags.objects.filter(name=tag).first()
  119. if tag_obj is None:
  120. obj = models.Tags(name=tag)
  121. obj.save()
  122. tags_id.append(obj.pk)
  123. else:
  124. tags_id.append(tag_obj.pk)
  125. if len(tags_id) > 0:
  126. article_obj.tags.set(tags_id)
  127. # models.Article.objects.filter(id=int(pk)).update(title=title, intro=intro, category=category_obj,
  128. # html_text=html_text,
  129. # markdown_text=markdown_text,
  130. # type=type_, status=status,
  131. # tags=str(tags).split(',')
  132. # )
  133. article_obj.title = title
  134. article_obj.intro = intro
  135. article_obj.category = category_obj
  136. article_obj.html_text = html_text
  137. article_obj.markdown_text = markdown_text
  138. article_obj.type = type_
  139. article_obj.status = status
  140. article_obj.is_top = is_top
  141. article_obj.save()
  142. return JsonResponse({"success": True, "message": "修改成功"})
  143. else:
  144. raise ServerException("错误的请求")
  145. @login_required(login_url='/')
  146. def add_article(request):
  147. if request.method == 'POST':
  148. title = request.POST['title']
  149. intro = request.POST['intro']
  150. category = request.POST['category']
  151. html_text = request.POST['html']
  152. markdown_text = request.POST['markdown']
  153. type_ = request.POST['type']
  154. status = request.POST['status']
  155. tags = request.POST['tags']
  156. is_top = request.POST['is_top']
  157. category_obj = models.Category.objects.get(id=category)
  158. now_utc = timezone.now() # aware UTC 时间
  159. # ① 如果你想要 UTC+8:
  160. beijing_time = now_utc + timedelta(hours=8)
  161. article_obj = models.Article.objects.create(title=title, intro=intro, category=category_obj,
  162. html_text=html_text,
  163. markdown_text=markdown_text,
  164. type=type_, status=status, user=request.user,
  165. created_time=beijing_time,
  166. is_top=is_top
  167. )
  168. tags_id = []
  169. for tag in str(tags).split(','):
  170. if tag == '':
  171. break
  172. else:
  173. tag_obj = models.Tags.objects.filter(name=tag).first()
  174. if tag_obj is None:
  175. obj = models.Tags(name=tag)
  176. obj.save()
  177. tags_id.append(obj.pk)
  178. else:
  179. tags_id.append(tag_obj.pk)
  180. if len(tags_id) > 0:
  181. article_obj.tags.set(tags_id)
  182. return JsonResponse({"success": True, "message": "添加成功"})
  183. else:
  184. raise ServerException("错误的请求")
  185. @login_required(login_url='/')
  186. def add_media(request):
  187. if request.method == 'POST':
  188. title = request.POST['title']
  189. category = request.POST['category']
  190. type_ = request.POST['type']
  191. status = request.POST['status']
  192. tags = request.POST['tags']
  193. cover = request.POST['cover_id']
  194. music_id = request.POST['music_id']
  195. cover_obj = models.FileRecord.objects.get(id=cover)
  196. music_obj = models.FileRecord.objects.get(id=music_id)
  197. now_utc = timezone.now() # aware UTC 时间
  198. # ① 如果你想要 UTC+8:
  199. beijing_time = now_utc + timedelta(hours=8)
  200. category_obj = models.Category.objects.get(id=category)
  201. article_obj = models.Article.objects.create(title=title, category=category_obj,
  202. type=type_, status=status, user=request.user,
  203. created_time=beijing_time,
  204. cover=cover_obj, music=music_obj
  205. )
  206. if tags != 'null':
  207. article_obj.tags.set(str(tags).split(','))
  208. return JsonResponse({"success": True, "message": "添加成功"})
  209. else:
  210. raise ServerException("错误的请求")
  211. @login_required(login_url='/')
  212. def add_music(request):
  213. if request.method == 'POST':
  214. title = request.POST['title']
  215. category = request.POST['category']
  216. type_ = request.POST['type']
  217. status = request.POST['status']
  218. tags = request.POST['tags']
  219. cover = request.POST['cover_id']
  220. music_id = request.POST['music_id']
  221. cover_obj = models.FileRecord.objects.get(id=cover)
  222. music_obj = models.FileRecord.objects.get(id=music_id)
  223. category_obj = models.Category.objects.get(id=category)
  224. article_obj = models.Article.objects.create(title=title, category=category_obj,
  225. type=type_, status=status, user=request.user,
  226. created_time=datetime.now(),
  227. cover=cover_obj, music=music_obj
  228. )
  229. if tags != 'null':
  230. article_obj.tags.set(str(tags).split(','))
  231. return JsonResponse({"success": True, "message": "添加成功"})
  232. else:
  233. raise ServerException("错误的请求")
  234. def set_tag(articles):
  235. for i in range(len(articles)):
  236. tags = models.Tags.objects.raw(
  237. 'select * from blog_tags left join blog_article_tags bat on blog_tags.id = bat.tags_id where bat.article_id = {0}'.format(
  238. articles[i]['id']))
  239. tags_field = []
  240. for item in tags:
  241. tags_field.append(item.name)
  242. articles[i]['tags'] = tags_field
  243. def get_article(top: int = -1, page: int = -1, is_paginator: bool = False, category: models.Category = None,
  244. tag: models.Tags = None, search_category: str = None, search_title: str = None,
  245. search_content: str = None, date_record: str = None,
  246. draft: bool = False):
  247. if category is None and tag is None and date_record is None and draft == False:
  248. search_dict = dict()
  249. search_dict['status'] = 1
  250. if search_title:
  251. search_dict['title__contains'] = search_title
  252. if search_content:
  253. search_dict['markdown_text__contains'] = search_content
  254. if search_category:
  255. search_dict['category'] = search_category
  256. articles = models.Article.objects.filter(**search_dict).order_by('-created_time').values(
  257. 'id', 'title', 'intro', 'category',
  258. 'user', 'created_time', 'type',
  259. 'cover__file_net_path',
  260. 'music__file_net_path', 'status',
  261. 'category__name',
  262. 'user__first_name', 'user_id',
  263. 'user__last_name',
  264. 'is_top', 'html_text')
  265. elif date_record is not None:
  266. date_format = "%Y-%m"
  267. date = datetime.strptime(date_record, date_format)
  268. articles = models.Article.objects.filter(created_time__year=date.year, created_time__month=date.month).order_by(
  269. '-created_time').values('id', 'title',
  270. 'intro',
  271. 'category',
  272. 'user',
  273. 'created_time',
  274. 'type',
  275. 'cover__file_net_path',
  276. 'music__file_net_path',
  277. 'status',
  278. 'category__name',
  279. 'user__first_name',
  280. 'user_id',
  281. 'user__last_name',
  282. 'is_top',
  283. 'html_text').distinct()
  284. elif tag is not None:
  285. articles = models.Article.objects.filter(tags__name=tag.name).order_by('-created_time').values('id', 'title',
  286. 'intro',
  287. 'category',
  288. 'user',
  289. 'created_time',
  290. 'type',
  291. 'cover__file_net_path',
  292. 'music__file_net_path',
  293. 'status',
  294. 'category__name',
  295. 'user__first_name',
  296. 'user_id',
  297. 'user__last_name',
  298. 'tags__name',
  299. 'is_top',
  300. 'html_text')
  301. elif draft:
  302. search_dict = dict()
  303. search_dict['status'] = 0
  304. if search_title:
  305. search_dict['title__contains'] = search_title
  306. if search_content:
  307. search_dict['markdown_text__contains'] = search_content
  308. if search_category:
  309. search_dict['category'] = search_category
  310. articles = models.Article.objects.filter(**search_dict).order_by('-created_time').values('id', 'title',
  311. 'intro',
  312. 'category',
  313. 'user',
  314. 'created_time',
  315. 'type',
  316. 'cover__file_net_path',
  317. 'music__file_net_path',
  318. 'status',
  319. 'category__name',
  320. 'user__first_name',
  321. 'user_id',
  322. 'user__last_name',
  323. 'is_top',
  324. 'html_text').distinct()
  325. else:
  326. articles = models.Article.objects.filter(category=category).order_by('-created_time').values('id', 'title',
  327. 'intro',
  328. 'category',
  329. 'user',
  330. 'created_time',
  331. 'type',
  332. 'cover__file_net_path',
  333. 'music__file_net_path',
  334. 'status',
  335. 'category__name',
  336. 'user__first_name',
  337. 'user_id',
  338. 'user__last_name',
  339. 'is_top',
  340. 'html_text')
  341. if is_paginator:
  342. if page <= 0:
  343. page = 1
  344. paginator = Paginator(articles, 15)
  345. try:
  346. articles = paginator.page(page)
  347. except PageNotAnInteger:
  348. articles = paginator.page(1)
  349. except EmptyPage:
  350. articles = paginator.page(paginator.num_pages)
  351. set_tag(articles=articles)
  352. return articles
  353. else:
  354. articles = list(articles)
  355. if top > -1:
  356. articles = articles[:top]
  357. set_tag(articles=articles)
  358. return articles
  359. # return JsonResponse({'all_article': json.loads(json.dumps(articles, default=str))})
  360. @login_required(login_url='/')
  361. def get_all_article(request):
  362. articles = models.Article.objects.order_by('-created_time').values('id', 'title',
  363. 'intro',
  364. 'category',
  365. 'user',
  366. 'created_time',
  367. 'type',
  368. 'cover__file_net_path',
  369. 'music__file_net_path',
  370. 'status',
  371. 'category__name',
  372. 'user__first_name', 'user_id',
  373. 'user__last_name')
  374. return JsonResponse(json.loads(json.dumps(list(articles), default=str)), safe=False)
  375. @login_required(login_url='/')
  376. def delete_article(request):
  377. if request.method == 'GET':
  378. id = request.GET.get("id")
  379. article = models.Article.objects.get(id=int(id))
  380. article.tags.clear()
  381. article.delete()
  382. return HttpResponseRedirect('/management/article') # 跳转到主界面
  383. else:
  384. raise ServerException("错误的请求")