from django.shortcuts import render, get_object_or_404, redirect
from django.core.mail import send_mail
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from .models import Post
from .forms import EmailPostForm, CommentForm, SearchForm, PostForm, PostUpdateForm
from django.db.models import Count
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from django.http import JsonResponse, HttpResponse
from django.views.decorators.http import require_POST
from common.decorators import ajax_required
from actions.utils import create_action, delete_action
import redis
from django.conf import settings
from django.db.models import Q
# connect to redis
r = redis.StrictRedis(host=settings.REDIS_HOST,
port=settings.REDIS_PORT,
db=settings.REDIS_DB)
# Create your views here.
def post_list(request):
posts = Post.objects.all()
tag = request.GET.get('tag')
if tag and tag != 'None':
if tag == '收藏':
posts = request.user.posts_liked.all()
else:
posts = posts.filter(tags__name__in=[tag])
paginator = Paginator(posts, 9)
page = request.GET.get('page')
form = SearchForm()
query = None
if 'query' in request.GET:
form = SearchForm(request.GET)
if form.is_valid():
query = form.cleaned_data['query']
results = Post.objects.filter(
Q(title__icontains=query)
)
return render(request,
'article/search.html',
{'form': form,
'query': query,
'results': results})
try:
posts = paginator.page(page)
except PageNotAnInteger:
# 如果页数不是整数,就返回第一页
posts = paginator.page(1)
except EmptyPage:
# 如果是不存在的页数,而且请求是AJAX请求,返回空字符串
if request.is_ajax():
return HttpResponse('')
# 如果页数超范围,显示最后一页
posts = paginator.page(paginator.num_pages)
if request.is_ajax():
return render(request, 'article/list_ajax.html', {'posts': posts, 'tag': tag, 'form': form})
return render(request, 'article/list.html', {'posts': posts, 'tag': tag, 'form': form})
@login_required
def post_detail(request, id):
post = get_object_or_404(Post, id=id)
# increment total post views by 1
total_views = r.incr('post:{}:views'.format(post.id))
# increment post ranking by 1
r.zincrby('post_ranking', post.id, 1)
# 列出文章对应的所有活动的评论
comments = post.comments.all()
new_comment = None
if request.method == 'POST':
comment_form = CommentForm(request.POST)
if comment_form.is_valid():
# 通过表单直接创建新数据对象,但是不要保存到数据库中
new_comment = comment_form.save(commit=False)
# 设置外键为当前文章
new_comment.post = post
new_comment.author = request.user
create_action(request.user, 'commented post', post)
# 将评论数据对象写入数据库
new_comment.save()
else:
comment_form = CommentForm()
# 显示相近Tag的文章列表
post_tags_ids = post.tags.values_list('id', flat=True)
similar_tags = Post.objects.filter(tags__in=post_tags_ids).exclude(id=post.id)
similar_posts = similar_tags.annotate(same_tags=Count('tags')).order_by('-same_tags', '-updated')[:4]
return render(request, 'article/detail.html',
{'post': post, 'comments': comments, 'new_comment': new_comment, 'comment_form': comment_form,
'similar_posts': similar_posts, 'total_views': total_views})
def post_share(request, id):
# 通过id 获取 post 对象
post = get_object_or_404(Post, id=id)
sent = False
if request.method == 'POST':
# 表单被提交
form = EmailPostForm(request.POST)
if form.is_valid():
# 验证表单数据
cd = form.cleaned_data
# 发送邮件......
post_url = request.build_absolute_uri(post.get_absolute_url())
subject = '{} ({}) recommends you reading "{}"'.format(cd['name'], cd['email'], post.title)
message = 'Read "{}" at {}\n\n{}\'s comments:{}'.format(post.title, post_url, cd['name'], cd['comments'])
send_mail(subject, message, 'lee0709@vip.sina.com', [cd['to']])
sent = True
else:
form = EmailPostForm()
return render(request, 'article/share.html', {'post': post, 'form': form})
def post_search(request):
form = SearchForm()
query = None
results = []
if 'query' in request.GET:
form = SearchForm(request.GET)
if form.is_valid():
query = form.cleaned_data['query']
results = Post.objects.filter(
Q(title__icontains=query)
)
return render(request,
'article/search.html',
{'form': form,
'query': query,
'results': results})
@login_required
def post_create(request):
if request.method == 'POST':
# 表单被提交
form = PostForm(data=request.POST, files=request.FILES)
if form.is_valid():
new_item = form.save(commit=False)
# 将当前用户附加到数据对象上
new_item.author = request.user
new_item.save()
create_action(request.user, 'created post', new_item)
form.save_m2m()
messages.success(request, 'Post added successfully')
# 重定向到新创建的数据对象的详情视图
return redirect(new_item.get_absolute_url())
else:
return redirect('article:post_list')
else:
# 根据GET请求传入的参数建立表单对象
form = PostForm(data=request.GET)
return render(request, 'article/create.html', {'form': form})
@login_required
def post_update(request, id):
post = get_object_or_404(Post, id=id)
if request.user != post.author:
return redirect(post.get_absolute_url())
if request.method == 'POST':
form = PostUpdateForm(instance=post, data=request.POST, files=request.FILES)
if form.is_valid():
form.save()
messages.success(request, 'Post updated successfully')
return redirect(post.get_absolute_url())
else:
messages.error(request, 'Error updating your profile')
return redirect(post.get_absolute_url())
else:
form = PostForm(instance=post)
return render(request, 'article/update.html', {'form': form})
@login_required
def post_delete(request, id):
post = get_object_or_404(Post, id=id)
if request.user != post.author:
return redirect(post.get_absolute_url())
delete_action(post)
post.delete()
return redirect('article:post_list')
@ajax_required
@login_required
@require_POST
def post_like(request):
post_id = request.POST.get('id')
action = request.POST.get('action')
if post_id and action:
try:
post = Post.objects.get(id=post_id)
if action == 'like':
post.users_like.add(request.user)
create_action(request.user, 'likes', post)
else:
post.users_like.remove(request.user)
return JsonResponse({'status': 'ok'})
except:
pass
return JsonResponse({'status': 'ko'})
def post_ranking(request):
# get post ranking dictionary
post_ranking = r.zrange('post_ranking', 0, -1, desc=True)[:10]
post_ranking_ids = [int(id) for id in post_ranking]
# get most viewed posts
most_viewed = list(Post.objects.filter(
id__in=post_ranking_ids))
most_viewed.sort(key=lambda
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
CSDN IT狂飙上传的代码均可运行,功能ok的情况下才上传的,直接替换数据即可使用,小白也能轻松上手 【资源说明】 Python高分项目 基于Django+Sqlite3实现的在线二手交易平台源码+资料齐全+部署文档.zip 1、代码压缩包内容 代码的项目文件 部署文档文件 2、代码运行版本 python3.7或者3.7以上的版本;若运行有误,根据提示GPT修改;若不会,私信博主(问题描述要详细) 3、运行操作步骤 步骤一:将代码的项目目录使用IDEA打开(IDEA要配置好python环境) 步骤二:根据部署文档或运行提示安装项目所需的库 步骤三:IDEA点击运行,等待程序服务启动完成 4、python资讯 如需要其他python项目的定制服务,可后台私信博主(注明你的项目需求) 4.1 python或人工智能项目辅导 4.2 python或人工智能程序定制 4.3 python科研合作 Django、Flask、Pytorch、Scrapy、PyQt、爬虫、可视化、大数据、推荐系统、人工智能、大模型
资源推荐
资源详情
资源评论
收起资源包目录
Python高分项目 基于Django+Sqlite3实现的在线二手交易平台源码+资料齐全+部署文档.zip (579个子文件)
AUTHORS 6KB
editormd.min.css 60KB
ambiance.css 26KB
w3.css 23KB
codemirror.css 8KB
codemirror.min.css 5KB
Email-Styles.css 5KB
mdn-like.css 5KB
solarized.css 5KB
Custom-Account-Styles.css 3KB
merge.css 3KB
lint.css 3KB
xq-dark.css 3KB
lesser-dark.css 2KB
pastel-on-dark.css 2KB
xq-light.css 2KB
tomorrow-night-eighties.css 2KB
erlang-dark.css 2KB
zenburn.css 2KB
twilight.css 2KB
midnight.css 2KB
vibrant-ink.css 2KB
mbo.css 2KB
base16-dark.css 2KB
base16-light.css 2KB
tern.css 2KB
3024-night.css 2KB
paraiso-dark.css 2KB
paraiso-light.css 2KB
tomorrow-night-bright.css 2KB
3024-day.css 2KB
blackboard.css 2KB
colorforth.css 2KB
the-matrix.css 2KB
night.css 2KB
rubyblue.css 2KB
monokai.css 1KB
cobalt.css 1KB
simplescrollbars.css 1KB
eclipse.css 1KB
neo.css 932B
elegant.css 768B
neat.css 693B
show-hint.css 662B
dialog.css 502B
tiki.css 440B
foldgutter.css 435B
tiddlywiki.css 220B
matchesonscrollbar.css 188B
fullscreen.css 116B
ambiance-mobile.css 103B
scala.html 28KB
index.html 22KB
index.html 17KB
index.html 13KB
index.html 13KB
detail.html 12KB
index.html 11KB
index.html 10KB
index.html 9KB
index.html 8KB
index.html 8KB
index.html 7KB
index.html 7KB
index.html 6KB
index.html 6KB
index.html 6KB
detail.html 6KB
index.html 6KB
index.html 6KB
index.html 6KB
index.html 5KB
dashboard.html 5KB
index.html 5KB
index.html 4KB
index.html 4KB
index.html 4KB
index.html 4KB
index.html 4KB
header.html 4KB
index.html 4KB
index.html 4KB
less.html 4KB
index.html 4KB
index.html 3KB
list.html 3KB
index.html 3KB
email.html 3KB
index.html 3KB
index.html 3KB
index.html 3KB
index.html 3KB
index.html 3KB
index.html 3KB
scss.html 3KB
index.html 3KB
index.html 3KB
base.html 3KB
index.html 3KB
index.html 3KB
共 579 条
- 1
- 2
- 3
- 4
- 5
- 6
资源评论
IT狂飙
- 粉丝: 4839
- 资源: 2652
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 考虑多风场出力相关性的可再生能源场景生成 风电场景生成,并通过聚类算法场景削减成几个场景,每个场景都有确定的出现概率 完美复现《考虑多风电场出力 Copula 相关关系的场景生成方法》 Copula
- 卫星俯视物体检测8-YOLO(v5至v9)、COCO、CreateML、Darknet、Paligemma、TFRecord、VOC数据集合集.rar
- hex文件转bin文件的源代码上传
- 分布式微电网能源交易算法matlab源代码, 代码按照高水平文章复现,保证正确 孤岛微电网之间的能源交易问题,提出了一种分布式算法 这个问题由几个通过任意拓扑交能量流的岛屿微网格组成 提出了一种基
- IMG_1734685462921.png
- 卫星俯视物体检测7-YOLO(v5至v9)、COCO、CreateML、Darknet、Paligemma、TFRecord、VOC数据集合集.rar
- 卫星俯视物体检测5-YOLO(v5至v9)、COCO、CreateML、Darknet、Paligemma、TFRecord、VOC数据集合集.rar
- pyqt6-plugins-6.4.2.2.3-py3-none-any.whl
- chromedriver.exe【版本:131.0.6778.204,谷歌浏览器驱动,自动化测试框架,WebUI自动化,浏览器交互,Chrome驱动、Selenium自动化、Python自动化测试】
- TypeScript-main.zip.zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功