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

Posted xuyiqing

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python的Django框架完成一个完整的论坛(3.创建app的models.pyviews.py源码)相关的知识,希望对你有一定的参考价值。

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})

 

以上是关于Python的Django框架完成一个完整的论坛(3.创建app的models.pyviews.py源码)的主要内容,如果未能解决你的问题,请参考以下文章

Python的Django框架完成一个完整的论坛(2.urls.py配置静态文件)

Python的Django框架完成一个完整的论坛(4.项目所需的其他py文件源码)

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

如何使用Django编写手机App服务端后台

python django怎么添加css-CSDN论坛

如何用django开发一个简易个人Blog-Python