您的位置:首页 > 移动开发

Python的Django框架完成一个完整的论坛(3.创建app的models.py、views.py源码)

2018-01-12 12:00 1186 查看
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})
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐