Python的Django框架完成一个完整的论坛(3.创建a…
2018-06-18 00:29:32来源:未知 阅读 ()
models.py:
from django.db import models class UserInfo(models.Model): """ 用户信息表 """ nid = models.BigAutoField(primary_key=True) username = models.CharField(verbose_name='用户名', max_length=32, unique=True) password = models.CharField(verbose_name='密码', max_length=64) avatar = models.ImageField(verbose_name='头像', default='static/imgs/avatar/default.png') qq = models.CharField(verbose_name='qq', max_length=32) article_count = models.IntegerField(verbose_name='文章个数', default=0) class Article(models.Model): """ 文章表 """ nid = models.BigAutoField(primary_key=True) title = models.CharField(verbose_name='文章标题', max_length=128) summary = models.CharField(verbose_name='文章简介', max_length=255) read_count = models.IntegerField(default=0) comment_count = models.IntegerField(default=0) up_count = models.IntegerField(default=0) create_time = models.DateTimeField(verbose_name='创建时间', auto_now_add=True) author = models.ForeignKey(verbose_name='作者', to='UserInfo', to_field='nid', on_delete=models.CASCADE) type_choices = [ (1, "学习"), (2, "游戏"), (3, "感情"), (4, "生活"), ] article_type_id = models.IntegerField(choices=type_choices, default=None) class ArticleDetail(models.Model): """ 文章详细表 """ content = models.TextField(verbose_name='文章内容') article = models.OneToOneField(verbose_name='所属文章', to='Article', to_field='nid', on_delete=models.CASCADE) class Comment(models.Model): """ 评论表 """ nid = models.BigAutoField(primary_key=True) content = models.CharField(verbose_name='评论内容', max_length=255) create_time = models.DateTimeField(verbose_name='创建时间', auto_now_add=True) article = models.ForeignKey(verbose_name='评论文章', to='Article', to_field='nid', on_delete=models.CASCADE) user = models.ForeignKey(verbose_name='评论者', to='UserInfo', to_field='nid', on_delete=models.CASCADE) class Reply(models.Model): """ 回复表 """ nid = models.BigAutoField(primary_key=True) article = models.ForeignKey(verbose_name="回复文章", to="Article", to_field="nid", on_delete=models.CASCADE) content = models.CharField(verbose_name="回复内容", max_length=255) user = models.ForeignKey(verbose_name="回复用户", to='UserInfo', to_field='nid', on_delete=models.CASCADE) comment_reply = models.ForeignKey(verbose_name="回复评论", to='Comment', to_field='nid', on_delete=models.CASCADE) class Up(models.Model): """ 记录赞表 """ nid = models.BigAutoField(primary_key=True) article = models.ForeignKey(verbose_name='文章', to='Article', to_field='nid', on_delete=models.CASCADE) user = models.ForeignKey(verbose_name='赞用户', to='UserInfo', to_field='nid', on_delete=models.CASCADE) up = models.BooleanField(verbose_name='是否赞')
记得写完后打开cmd
python manage.py makemigrations
python manage.py migrate
views.py:
import os import json import uuid from web import models from io import BytesIO from django.urls import reverse from utils.pagination import Pagination from django.shortcuts import render from django.shortcuts import redirect from django import forms as django_forms from django.shortcuts import HttpResponse from django.db.utils import IntegrityError from django.forms import fields as django_fields from utils.check_code import create_validate_code from django.core.exceptions import ValidationError def check_login(func): """ 验证登录状态装饰器 :param func: :return: """ def inner(request, *args, **kwargs): if request.session.get('user_info'): return func(request, *args, **kwargs) else: return redirect('/login.html') return inner class BaseForm(object): """ Form基类 """ def __init__(self, request, *args, **kwargs): self.request = request super(BaseForm, self).__init__(*args, **kwargs) class LoginForm(BaseForm, django_forms.Form): """ 验证登录的Form """ username = django_fields.CharField( min_length=6, max_length=20, error_messages={'required': '用户名不能为空.', 'min_length': "用户名长度不能小于6个字符", 'max_length': "用户名长度不能大于32个字符"} ) password = django_fields.CharField( min_length=6, max_length=32, error_messages={'required': '密码不能为空.', 'min_length': "密码长度不能小于6个字符", 'max_length': "密码长度不能大于32个字符"} ) rmb = django_fields.IntegerField(required=False) check_code = django_fields.CharField( error_messages={'required': '验证码不能为空.'} ) def clean_check_code(self): if self.request.session.get('CheckCode').upper() != self.request.POST.get('check_code').upper(): raise ValidationError(message='验证码错误', code='invalid') class RegisterForm(BaseForm, django_forms.Form): """ 验证注册的Form """ username = django_fields.CharField( min_length=6, max_length=20, error_messages={'required': '用户名不能为空.', 'min_length': "用户名长度不能小于6个字符", 'max_length': "用户名长度不能大于32个字符"} ) password = django_fields.CharField( min_length=6, max_length=32, error_messages={'required': '密码不能为空.', 'min_length': "密码长度不能小于6个字符", 'max_length': "密码长度不能大于32个字符"} ) confirm_password = django_fields.CharField( min_length=6, max_length=32, error_messages={'required': '密码不能为空.', 'min_length': "密码长度不能小于6个字符", 'max_length': "密码长度不能大于32个字符"} ) qq = django_fields.IntegerField() check_code = django_fields.CharField( error_messages={'required': '验证码不能为空.'} ) def clean_check_code(self): if self.request.session.get('CheckCode').upper() != self.request.POST.get('check_code').upper(): raise ValidationError(message='验证码错误', code='invalid') # Create your views here. def index(request, *args, **kwargs): """ 首页 展示所有 :param request: :return: """ article_type_list = models.Article.type_choices if kwargs: article_type_id = int(kwargs['article_type_id']) base_url = reverse('index', kwargs=kwargs) else: article_type_id = None base_url = '/' data_count = models.Article.objects.filter(**kwargs).count() page_obj = Pagination(request.GET.get('p'), data_count) article_list = models.Article.objects.filter(**kwargs).order_by('-nid')[page_obj.start:page_obj.end] page_str = page_obj.page_str(base_url) article_nid_list = models.Article.objects.values_list('nid') top_read = [] count = 0 for i in article_nid_list: count += 1 if count <= 10: article_obj = models.Article.objects.filter(nid=i[0]) read_count = article_obj.values('read_count').first().get('read_count') top_read.append({'nid': article_obj.values('nid').first().get('nid'), 'read_count': read_count, 'title': article_obj.values('title').first().get('title'), 'article_type_id': article_obj.values('article_type_id').first().get('article_type_id'), 'author_name': article_obj.values('author__username').first().get('author__username')}) top_read.sort(key=lambda obj: obj.get('read_count'), reverse=True) return render( request, 'home.html', { 'article_list': article_list, 'article_type_id': article_type_id, 'article_type_list': article_type_list, 'page_str': page_str, 'top_read': top_read, } ) def detail(request, article_type_id, author_name, nid): """ 文章详情 :param request: :param article_type_id: :param author_name: :param nid: :return: """ content_title = models.Article.objects.filter(nid=nid).values('title').first().get('title') content = models.ArticleDetail.objects.filter(article_id=nid).values('content').first().get('content') qq = models.UserInfo.objects.filter(username=author_name).values('qq').first().get('qq') article = models.Article.objects.filter(nid=nid).first() comment_list = models.Comment.objects.filter(article=article) reply_list = models.Reply.objects.filter(article_id=nid) if request.method == "GET": new_read_count = int(models.Article.objects.filter(nid=nid).values('read_count').first().get('read_count')) + 1 models.Article.objects.filter(nid=nid).update(read_count=str(new_read_count)) return render(request, 'article_detail.html', {'content_title': content_title, 'content': content, 'author_name': author_name, 'comment_list': comment_list, 'qq': qq, 'nid': nid, 'article': article, 'reply_list': reply_list}) def login(request): """ 登录 :param request: :return: """ if request.method == 'GET': return render(request, 'login.html') elif request.method == 'POST': result = {'status': False, 'message': None, 'data': None} form = LoginForm(request=request, data=request.POST) if form.is_valid(): username = form.cleaned_data.get('username') password = form.cleaned_data.get('password') user_info = models.UserInfo.objects. \ filter(username=username, password=password). \ values('nid', 'username').first() if not user_info: result['message'] = '用户名或密码错误' else: result['status'] = True request.session['user_info'] = user_info if form.cleaned_data.get('rmb'): request.session.set_expiry(60 * 60 * 24 * 7) else: if 'check_code' in form.errors: result['message'] = '验证码错误或者过期' else: result['message'] = '用户名或密码错误' return HttpResponse(json.dumps(result)) def logout(request): """ 注销 :param request: :return: """ request.session.set_expiry = 1 request.session.clear() return redirect('/') def check_code(request): """ 自动生成验证码,用到Python的PIL模块 :param request: :return: """ stream = BytesIO() img, code = create_validate_code() img.save(stream, 'PNG') request.session['CheckCode'] = code return HttpResponse(stream.getvalue()) def register(request): """ 注册 :param request: :return: """ if request.method == "GET": return render(request, 'register.html') elif request.method == "POST": result = {'status': False, 'message': None, 'data': None} form = RegisterForm(request=request, data=request.POST) if form.is_valid(): username = form.cleaned_data.get('username') password = form.cleaned_data.get('password') confirm_password = form.cleaned_data.get('confirm_password') qq = form.cleaned_data.get('qq') if password != confirm_password: result['message'] = '两次输入的密码不一致' else: try: models.UserInfo.objects.create( username=username, password=password, qq=qq ) except IntegrityError: result['message'] = '用户名已被注册' else: result['status'] = True else: if 'check_code' in form.errors: result['message'] = "验证码错误或过期" elif 'username' in form.errors: result['message'] = "用户名格式错误,至少6位" elif 'password' in form.errors or 'confirm_password' in form.errors: result['message'] = "密码格式错误,至少6位" else: result['message'] = "QQ格式错误" return HttpResponse(json.dumps(result)) @check_login def write(request, author_name): """ 写文章 :param request: :return: """ if request.method == "GET": return render(request, 'write_article.html', {'author_name': author_name}) elif request.method == "POST": title = request.POST.get('title') summary = request.POST.get('summary') content = request.POST.get('content') article_type_id = request.POST.get('article_type') author_id = models.UserInfo.objects.filter(username=author_name).values('nid').first().get('nid') obj = models.Article.objects.create(title=title, summary=summary, article_type_id=article_type_id, author_id=author_id) models.ArticleDetail.objects.create(content=content, article=obj) new_article_count = int( models.UserInfo.objects.filter(nid=author_id).values('article_count').first().get('article_count')) + 1 models.UserInfo.objects.filter(nid=author_id).update(article_count=str(new_article_count)) return redirect('/') @check_login def edit(request, author_name, article_id): """ 修改文章 :param request: :param author_name: :param article_id: :return: """ if request.method == "GET": title = models.Article.objects.filter(nid=article_id).values('title').first().get('title') summary = models.Article.objects.filter(nid=article_id).values('summary').first().get('summary') article_type_id = int( models.Article.objects.filter(nid=article_id).values('article_type_id').first().get('article_type_id')) content = models.ArticleDetail.objects.filter(article_id=article_id).values('content').first().get('content') return render(request, 'edit_article.html', {'author_name': author_name, 'title': title, 'summary': summary, 'article_type_id': article_type_id, 'content': content, 'article_id': article_id}) elif request.method == "POST": title = request.POST.get('title') summary = request.POST.get('summary') content = request.POST.get('content') article_type_id = request.POST.get('article_type') obj = models.Article.objects.filter(nid=article_id).first() models.Article.objects.filter(nid=obj.nid).update(title=title, summary=summary, article_type_id=article_type_id) models.ArticleDetail.objects.filter(article=obj).update(content=content) return redirect('/') @check_login def delete(request, article_id): """ 删除文章 :param request: :param article_id: :return: """ obj = models.Article.objects.filter(nid=article_id).first() models.ArticleDetail.objects.filter(article=obj).delete() models.Article.objects.filter(nid=obj.nid).delete() new_article_count = int( models.UserInfo.objects.filter(nid=request.session['user_info']['nid']).values('article_count').first().get( 'article_count')) - 1 models.UserInfo.objects.filter(nid=request.session['user_info']['nid']).update(article_count=str(new_article_count)) return redirect(to='/article_manage/' + request.session['user_info']['username']) @check_login def delete_comment(request): """ 删除评论 :param request: :return: """ nid = request.POST.get('comment_nid') models.Comment.objects.filter(nid=nid).delete() return HttpResponse("OK") @check_login def reply(request, username, nid): """ 评论 :param request: :param username: :param nid: :return: """ if request.method == "POST": new_comment_count = int( models.Article.objects.filter(nid=nid).values('comment_count').first().get('comment_count')) + 1 models.Article.objects.filter(nid=nid).update(comment_count=str(new_comment_count)) content = request.POST.get('content') user = models.UserInfo.objects.filter(username=username).first() models.Comment.objects.create(content=content, article_id=nid, user=user) return HttpResponse("OK") @check_login def comment_reply(request, comment_id, user_nid, article_id): """ 回复评论 :param request: :param comment_id: :param user_nid: :param article_id: :return: """ content = request.POST.get('content') models.Reply.objects.create(comment_reply_id=comment_id, content=content, user_id=user_nid, article_id=article_id) return HttpResponse("OK") @check_login def good(request, article_id, user_id): """ 点赞 :param request: :param article_id: :param user_id: :return: """ result = {'status': True} new_read_count = int( models.Article.objects.filter(nid=article_id).values('read_count').first().get('read_count')) - 1 models.Article.objects.filter(nid=article_id).update(read_count=str(new_read_count)) if models.Up.objects.filter(article_id=article_id, user_id=user_id): result = {'status': False} return HttpResponse(json.dumps(result)) else: models.Up.objects.create(up=False, article_id=article_id, user_id=user_id) new_up_count = int(models.Article.objects.filter(nid=article_id).values('up_count').first().get('up_count')) + 1 models.Article.objects.filter(nid=article_id).update(up_count=str(new_up_count)) models.Up.objects.filter(article_id=article_id, user_id=user_id).update(up=True) return HttpResponse(json.dumps(result)) @check_login def user_info(request, username): """ 查询用户信息 :param request: :param username: :return: """ if request.method == "GET": user = models.UserInfo.objects.filter(username=username).first() return render(request, 'user_info.html', {'user': user}) elif request.method == "POST": qq = request.POST.get('qq') password = request.POST.get('password') models.UserInfo.objects.filter(username=username).update(qq=qq, password=password) return HttpResponse("OK") @check_login def upload_avatar(request, nid): """ 头像上传以及预览 :param request: :param nid: :return: """ ret = {'status': False, 'data': None, 'message': None} if request.method == 'POST': file_obj = request.FILES.get('avatar_img') print(file_obj) if not file_obj: pass else: file_name = str(uuid.uuid4()) file_path = os.path.join('static/imgs/avatar', file_name) f = open(file_path, 'wb') for chunk in file_obj.chunks(): f.write(chunk) f.close() models.UserInfo.objects.filter(nid=nid).update(avatar=file_path) request.session['user_info']['avatar'] = file_path ret['status'] = True ret['data'] = file_path return HttpResponse(json.dumps(ret)) @check_login def article_manage(request, username): """ 文章管理 :param request: :param username: :return: """ if request.method == 'GET': user = models.UserInfo.objects.filter(username=username).first() article_list = models.Article.objects.filter(author=user) data_count = models.Article.objects.filter(author=user).count() page = Pagination(request.GET.get('p', 1), data_count) page_str = page.page_str(reverse('article', kwargs={'username': username})) print(article_list) return render(request, 'article_manage.html', {'user': user, 'article_list': article_list, 'page_str': page_str})
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- python3基础之“术语表(2)” 2019-08-13
- python3 之 字符串编码小结(Unicode、utf-8、gbk、gb2312等 2019-08-13
- Python3安装impala 2019-08-13
- 小白如何入门 Python 爬虫? 2019-08-13
- python_字符串方法 2019-08-13
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash