Django基础第十六天-BBS项目02

需求分析

  1. 登陆功能 (基于Ajax,图片验证码)
  2. 注册功能 (基于Ajax,基于forms验证)
  3. 博客首页
  4. 个人站点
  5. 文章详情
  6. 点赞,点踩
  7. 评论
    ——根评论
    ——子评论
  8. 后台管理
    ——文章展示
  9. 发布文章
    ——富文本编辑器
    ——防止xss攻击

settings.py

#指定上传头像的根路径
MEDIA_ROOT=os.path.join(BASE_DIR,'media')

TT=os.path.join(BASE_DIR,'BBS')

modles.py

class Article(models.Model):
    # 评论数、点赞数、点踩数字段
    comment_num = models.IntegerField(default=0)
    up_num = models.IntegerField(default=0)
    down_num = models.IntegerField(default=0)

urls.py

urlpatterns = [
    url(r"^$", views.index),
    url(r'^get_code/$', views.get_code),
    url(r'^register/$', views.register),
    # media配置,输入media/后任意字符都会响应到settings.MEDIA_ROOT中的,即media文件夹下avatar            
    文件内的文件内容(这里指图片)
    url(r"media/(?P<path>.*)$", serve, {"document_root": settings.MEDIA_ROOT}),
    url(r'index/', views.index),

view.py

def register(request):
    if request.is_ajax():
        back_msg={'user':None,'msg':None}
        name=request.POST.get('name')
        pwd=request.POST.get('pwd')
        re_pwd=request.POST.get('re_pwd')
        email=request.POST.get('email')
        myfile=request.FILES.get('myfile')  #注意:文件获取的方法是FILES
        print(request.POST)
        form_obj=myforms.RegForms(request.POST)
        if form_obj.is_valid():
            if myfile:
                UserInfo.objects.create_user(username=name,password=pwd,email=email,avatar=myfile)
            else:
                UserInfo.objects.create_user(username=name,password=pwd,email=email)
            back_msg['user']=name
            back_msg['msg']='注册成功'
        else:
            print(form_obj.errors)
            back_msg['msg']=form_obj.errors
        return JsonResponse(back_msg)
    form_obj=myforms.RegForms()
    return render(request,'register.html',{'form_obj':form_obj})

def index(request):
    article_list=Article.objects.all()

    return render(request,'index.html',{'article_list':article_list})

myform.py

# Django中的Form使用时一般有两种功能:
# 1、生成html标签
# 2、验证输入内容
from django import forms

# 不要将Widget与表单的fields字段混淆。表单字段负责验证输入并直接在模板中使用。而Widget负责渲染网页上HTML表单的输入元素和提取提交的原始数据。widget是字段的一个内在属性,用于定义字段在浏览器的页面里以何种HTML元素展现。
from django.forms import widgets

from mybbs import models
from django.core.exceptions import ValidationError


class RegForms(forms.Form):
    name = forms.CharField(max_length=9, label='用户名',
                           widget=widgets.TextInput(attrs={'class': 'form-control'}),
                           error_messages={'required': '该字段必填', 'max_length': '不能超长'}
                           )
    pwd = forms.CharField(max_length=9, label='密码',
                          widget=widgets.PasswordInput(attrs={'class': 'form-control'}),
                          error_messages={'required': '该字段必填', 'max_length': '不能超长'}
                          )
    re_pwd = forms.CharField(max_length=9, label='再次输入密码',
                             widget=widgets.PasswordInput(attrs={'class': 'form-control'}),
                             error_messages={'required': '该字段必填', 'max_length': '不能超长'}
                             )
    email = forms.EmailField(label='电子邮箱',
                             widget=widgets.EmailInput(attrs={'class': 'form-control'}),
                             error_messages={'required': '该字段必填', 'invalid': '不是邮箱格式'}
                             )

    def clean_name(self):   #局部钩子
        name = self.cleaned_data.get('name')  # cleaned_data 就是读取表单返回的值,返回类型为字典dict型
        user = models.UserInfo.objects.filter(username=name)
        if user:
            raise ValidationError('用户名已经存在')
        else:
            return name

    def clean(self):    #全局钩子
        pwd = self.cleaned_data.get('pwd')
        re_pwd = self.cleaned_data.get('re_pwd')
        if pwd and re_pwd:
            if pwd == re_pwd:
                return self.cleaned_data
            else:
                raise ValidationError('再次密码不一致')

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/bootstrap-3.3.7-dist/css/bootstrap.min.css">
    <script src="/static/jquery-3.3.1.js"></script>
    <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/bootstrap-3.3.7-dist/js/bootstrap.min.js">
    <title>首页</title>
</head>
<body>
{#头部信息#}
<nav class="navbar navbar-default">
    <div class="container-fluid">
        <!-- Brand and toggle get grouped for better mobile display -->
        <div class="navbar-header">
            <button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
                    data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="#">博客园</a>
        </div>

        <!-- Collect the nav links, forms, and other content for toggling -->
        <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
            <ul class="nav navbar-nav">
                <li class="active"><a href="#">首页 <span class="sr-only">(current)</span></a></li>
                <li><a href="#">文章</a></li>
            </ul>

            <ul class="nav navbar-nav navbar-right">
                {% if request.user.is_authenticated %}
                    <li><a href="#"></a></li>
                    <li class="dropdown">
                        <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
                           aria-expanded="false">更多操作 <span class="caret"></span></a>
                        <ul class="dropdown-menu">
                            <li><a href="#">修改密码</a></li>
                            <li><a href="#">后台管理</a></li>
                            <li><a href="#">退出登录</a></li>
                        </ul>
                    </li>
                {% else %}
                    <li><a href="/login/">登录</a></li>
                    <li><a href="/register/">注册</a></li>
                {% endif %}
            </ul>


        </div><!-- /.navbar-collapse -->
    </div><!-- /.container-fluid -->
</nav>

{#内容区域#}

<div class="container-fluid">
    <div class="row">
        <div class="col-md-3">

            <div>

                <div class="panel panel-primary">
                    <div class="panel-heading">左侧广告</div>
                    <div class="panel-body">
                        广告区
                    </div>
                </div>
                <div class="panel panel-danger">
                    <div class="panel-heading">左侧广告</div>
                    <div class="panel-body">
                        左侧广告
                    </div>
                </div>
                <div class="panel panel-default">
                    <div class="panel-heading">左侧广告</div>
                    <div class="panel-body">
                        广告
                    </div>
                </div>


            </div>
        </div>
        <div class="col-md-6">

            {% for article in article_list %}
                <div class="article_head"><a href=""><h5>{{ article.title }}</h5></a></div>
                <div>
                    <img height="40" width="40" src="/media/{{ article.user.avatar }}" alt="">  {# 拼接图像文件路径 #}
                    <span >{{ article.desc }}</span>
                </div>
                <div class="small" style="margin-top: 10px">
                <span><a href="">{{ article.user.username }}</a></span>
                <span>发布于 {{ article.create_date|date:"Y-m-d" }}</span>
                <span class="glyphicon glyphicon-comment">评论({{ article.comment_num }})</span>
                <span class="glyphicon glyphicon-thumbs-up">点赞({{ article.up_num }})</span>
                </div>
                <hr>

            {% endfor %}


        </div>
        <div class="col-md-3">

            <div>

                <div class="panel panel-default">
                    <div class="panel-heading">右侧广告</div>
                    <div class="panel-body">
                        点赞
                    </div>
                </div>
                <div class="panel panel-danger">
                    <div class="panel-heading">右侧广告</div>
                    <div class="panel-body">
                        广告一
                    </div>
                </div>
                <div class="panel panel-success">
                    <div class="panel-heading">右侧</div>
                    <div class="panel-body">
                        评论
                    </div>
                </div>


            </div>

        </div>
    </div>
</div>
</body>
</html>

admin.py

from django.contrib import admin

# Register your models here.

# 将各表信息添加到admin中去,在后台可对各表数据进行操作
from mybbs import models
admin.site.register(models.UserInfo)
admin.site.register(models.Blog)
admin.site.register(models.Tag)
admin.site.register(models.Category)
admin.site.register(models.Article)
admin.site.register(models.ArticleUpDown)
admin.site.register(models.Article2Tag)
admin.site.register(models.Comment)

register.py

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/bootstrap-3.3.7-dist/css/bootstrap.min.css">
    <script src="/static/jquery-3.3.1.js"></script>
    <title>注册页面</title>
    <style>
        #myimg {
            margin-left: 10px;
        }

        #myfile {
            display: none;
        }

        .error {
            color: red
        }
    </style>
</head>
<body>
<form action="" id="form">
    <div class="container-fluid">
        <div class="row">
            <div class="col-md-6 col-md-offset-3">
                <h1>注册页面</h1>
                {% csrf_token %}
                {% for foo in form_obj %}
                    <div class="form-group">
                        <label for="{{ foo.auto_id }}">{{ foo.label }}</label>
                        {{ foo }} <span class="error pull-right"></span>
                    </div>
                {% endfor %}
                <div class="form-group">
                    <label for="myfile">头像
                        <img src="/static/img/default.png" alt="" height="60" width="60" id="myimg">
                    </label>

                    <input type="file" id="myfile">

                </div>
                <div>
                    <input type="button" id="sub_btn" class="btn btn-danger" value="注册">
                </div>


            </div>
        </div>
    </div>
</form>

<script>
    $("#myfile").change(function () {
        var obj = $(this)[0].files[0]
        var read = new FileReader()
        read.readAsDataURL(obj)
        read.onload = function () {
            $("#myimg").attr('src', read.result)
        }
    })
    $("#sub_btn").click(function () {
        //alert(11)
        var formdata = new FormData()
        //传统方式
        //formdata.append('name',$("#id_name")
        var tt = $("#form").serializeArray()
        //console.log(tt)
        $.each(tt, function (index, value) {
            formdata.append(value.name, value.value)
        })
        formdata.append('myfile', $("#myfile")[0].files[0])
        $.ajax({
            url: '',
            type: 'post',
            processData: false,
            contentType: false,
            data: formdata,
            success: function (data) { {# 获取后台返回的结果 #}
                //console.log(data)
                if (data.user) {
                    {# 转跳至指定路径 #}
                    location.href = '/login/'
                } else {
                    $(".form-group").removeClass('has-error')
                    $("span.error").text("")
                    $.each(data.msg, function (index, value) {
                        console.log(index) {# index为字段名 #}
                        console.log(value)
                        console.log("#id_" + index)

                        if (index == '__all__') {
                            $("#id_re_pwd").next().text(value[0]).parent().addClass('has-error')
                        }
                        $("#id_" + index).next().text(value[0]).parent().addClass('has-error')
                    })
                }
            }
        })
    })
</script>
</body>
</html>

猜你喜欢

转载自blog.csdn.net/qq_17513503/article/details/82789507