BBS项目 部分主界面and个人博客界面代码详解

forms

 

from django import forms
#导入异常方法
from django.core.exceptions import ValidationError
from django.core.validators import RegexValidator
from bolg import models


# 创建登录form类
class LoginInfo(forms.Form):
# 创建账号字段
username = forms.CharField(
# 默认名称
label="用户名",
# 错误提示
error_messages={
# 不能为空
"required": "用户名不能为空"
},
# widget方法调用,可以定义类
widget=forms.widgets.TextInput(attrs={"class": "form-control"})

)

# 创建密码字段
password = forms.CharField(
# 默认名称
label="密码",
# 错误提示
error_messages={
# 不能为空
"required": "密码不能为空"
},
# widget方法调用,可以定义类
widget=forms.widgets.PasswordInput(attrs={"class": "form-control"})

)


# 创建注册form类
class RegForm(forms.Form):
#创建注册用户字段
username = forms.CharField(
label='用户名',
max_length=16,
min_length=4,
error_messages={
"max_length":"用户名最长不能超过16位",
"min_length": "用户名最短不能少于4位",
"required":"用户名不能为空",
},
widget=forms.widgets.TextInput(attrs={"class":"form-control"})
)
#创建注册密码字段
password = forms.CharField(
label='密码',
max_length=16,
min_length=6,
error_messages={
"max_length":"密码最长不能超过16位",
"min_length": "密码最短不能少于6位",
"required":"密码不能为空",
},
widget=forms.widgets.PasswordInput(attrs={"class":"form-control"})
)

#创建确认密码字段
re_password = forms.CharField(
label='确认密码',
max_length=16,
min_length=6,
error_messages={
"max_length":"确认密码最长不能超过16位",
"min_length": "确认密码最短不能少于6位",
"required":"确认密码不能为空",
},
widget=forms.widgets.PasswordInput(attrs={"class":"form-control"})
)

#创建手机号字段
phone=forms.CharField(
max_length=11,
min_length=11,
label="手机号码",
validators=[
RegexValidator(r'^\d{11}$', "手机号必须是11位数字"),
RegexValidator(r'^1[356789][0-9]{9}$', "手机号码格式不正确")
],
error_messages={
"max_length": "手机号长度为11位",
"min_length": "手机号长度为11位",
"required": "手机号不能为空",
},
widget=forms.widgets.TextInput(attrs={"class": "form-control"})
)

#局部钩子
def clean_username(self):
#去除username的值
value=self.cleaned_data.get("username")
if 'JPM' in value: #判断是否包含,包含就返回错误
raise ValidationError("不符合社会主义核心价值观!")
elif models.UserInfo.objects.filter(username=value): #判断是否能搜索到 能就返回错误信息
raise ValidationError("用户名重复!")
else:
return value #无错返回原值

#局部钩子
def clean_phone(self):
#去除username的值
value=self.cleaned_data.get("phone")
if models.UserInfo.objects.filter(phone=value): #判断是否能搜索到 能就返回错误信息
raise ValidationError("手机号重复!")
else:
return value #无错返回原值

#全局钩子,一般用于需要调用多个参数时,比如调用密码和确认密码
def clean(self):
#取密码
pwd=self.cleaned_data.get("password")
re_pwd=self.cleaned_data.get("re_password")

#做比较
#判断re_pwd 或 pwd有没有空 有的话直接跳错误,没有的再拿pwd和re_pwd比较
if re_pwd and pwd ==re_pwd:
#无错返回数据
return self.cleaned_data
else:
#有错返回异常
self.add_error("re_password","两次输入的密码不一样")
raise ValidationError("两次输入的密码不一样")

———————————————————————————————————————————————————————————————————————————————

url

 

"""bbs2 URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/1.11/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: url(r'^$', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.conf.urls import url, include
2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls'))
"""
from django.conf.urls import url,include
from django.contrib import admin
from bolg import views
from django.views.static import serve
from django.conf import settings
from bolg import urls as blog_urls



urlpatterns = [
url(r'^admin/', admin.site.urls),
#主界面
url(r'^$', views.index),
#登录
url(r'^login/', views.login),
#生成图片
url(r'^v_code/', views.v_code),
#主界面
url(r'^index/', views.index),
#注册
url(r'^reg/', views.reg),
#注销
url(r'^zhuxiao/', views.zhuxiao),
#查询media路径下的
url(r'^media/(?P<path>.*)$', serve, {"document_root": settings.MEDIA_ROOT}),
#用于转到二级个人页面
url(r'^bolg/', include(blog_urls)),

]

———————————————————————————————————————————————————————————————————————————————

views


# 主界面
def index(request):
# is_authenticated判断是否以登录,登录时必须在login存参数,否则无法生效
if request.user.is_authenticated():
#查找所有文章
article_obj = models.Article.objects.all()
# 把对象传递进去
return render(request, 'index.html', {"article_obj": article_obj})

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


# 个人界面
def home(request, username):
# 根据传来的用户名找用户
# first() 最上面的对象
user_obj = models.UserInfo.objects.filter(username=username).first()

# 无该用户就404
if not user_obj:
return HttpResponse('404')
else:
# 外键的正向查询
# 对象直接点外键字段名,获取对象
blog_obj = user_obj.blog

# 查当前用户的所有文章
# 外键的正向跨表查询user为要查表的对应字段__为跨表username为第二张表要查的字段名
# 经过filter筛选用户为username的
data = models.Article.objects.filter(user__username=username)

# 当前站点下的文章分类
# category_list = models.Category.objects.filter(blog=blog_obj)
# 统计数导入
from django.db.models import Count
# 先filter赛选出,此博客的分类,然后用annotate根据文章分组,统计数量,values字典拿值
category_list = models.Category.objects.filter(blog=blog_obj).annotate(num=Count("article")).values("title", "num")
#查询当前用户博客的所有标签
tag_obj = models.Tag.objects.filter(blog=blog_obj)
#查询格式化时间,然后根据id分组统计
date_list=models.Article.objects.extra(select={"time": "DATE_FORMAT(create_time, '%%Y-%%m')"}).values("time").annotate(
num=Count("nid")).values("time", "num")
#所有文章
article_obj = models.Article.objects.all()

return render(request, 'home.html', {'blog': blog_obj,
'article_list': data,
'category_list': category_list,
'tag_obj': tag_obj,
'date_list': date_list,
'article_obj': article_obj,
})

———————————————————————————————————————————————————————————————————————————————

 html-home

 

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{{ blog.title }}</title>
<link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.min.css">
<link rel="stylesheet" href="/static/mystyle.css">
{# <link rel="stylesheet" href="/media/themes/{{ blog.theme }}">#}

</head>
<body>

<nav class="navbar navbar-beise ">
<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="#"> {{ blog.title }}</a>
<a class="navbar-brand" href="/index/"> 首页</a>
</div>

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

<div class="container">
<div class="row">
<div class="col-md-3">
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">文章分类</h3>
</div>
<div class="panel-body ">
<ul class="list-unstyled">
{# 循环存储分类的列表#}
{% for category in category_list %}
<li><a href="#"> {{ category.title }}({{ category.num }})</a></li>
{% endfor %}
</ul>
</div>
</div>
<div class="panel panel-success">
<div class="panel-heading">
<h3 class="panel-title">文章标签</h3>
</div>
<div class="panel-body">
<ul class="list-unstyled">
{# 循环存储标签的列表#}
{% for tag in tag_obj %}
<li><a href="#"> {{ tag.title }}({{ tag.article_set.count }})</a></li>
{% endfor %}
</ul>
</div>
</div>
<div class="panel panel-info">
<div class="panel-heading">
<h3 class="panel-title">日期归档</h3>
</div>
<div class="panel-body">
<ul class="list-unstyled">
{# #循环存储时间的列表#}
{% for data in date_list %}
<li><a href="#"> {{ data.time }}({{ data.num }})</a></li>
{% endfor %}
</ul>
</div>
</div>
</div>
<div class="col-md-9">
{# 循环文章列表,拿文章对象传值#}
{% for article in article_obj %}
<div id="home-article-shang">
<h2>{{ article.title }}</h2>
</div>
<div id="home-article-zhong">
{{ article.desc }}
</div>
<div class="article-xia">
<a href="/bolg/{{ article.user.username }}"><span>{{ article.user.username }}</span></a>
<span>{{ article.create_time }}</span>
<span>点赞({{ article.up_count }})</span>
<span>评论({{ article.comment_count }})</span>
<hr>
</div>
{% endfor %}
</div>
</div>
</div>

</body>
</html>

———————————————————————————————————————————————————————————————————————————————

 html-index

 

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>主页</title>
<link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.min.css">
<link rel="stylesheet" href="/static/mystyle.css">
</head>
<body>
<nav class="navbar navbar-inverse">
<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="#">BBS</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>
</ul>
<ul class="nav navbar-nav navbar-right">
{# 判断传来的是否有对象,有就调用对象里的值,没有就登录注册#}
{% if request.user.username %}
{# 调用对象里的值进行操作#}
<li><img id="img_tou" src="/media/{{ request.user.avatar }}" alt=""></li>
<li><a href="/bolg/{{ request.user.username }}">{{ request.user.username }}</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="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li role="separator" class="divider"></li>
<li><a href="/zhuxiao/">注销</a></li>
</ul>
</li>
{% else %}
<li><a href="/login/">登录</a></li>
<li><a href="/reg/">注册</a></li>
{% endif %}

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

<div class="container-fluid">
<div class="row">
<div class="col-md-2 ">
<div class="panel panel-success">
<div class="panel-heading">
<h3 class="panel-title">Panel title</h3>
</div>
<div class="panel-body">
Panel content
</div>
</div>
</div>
<div class="col-md-8 ">
{# 循环文章列表,拿文章对象传值#}
{% for article in article_obj %}
<div>
<h2>{{ article.title }}</h2>
</div>
<div>
<div class="media">
<div class="media-left">
<a href="#">
<img id="article-avatar" class="media-object" src="/media/{{ article.user.avatar }}"
alt="">
</a>
</div>
<div class="media-body">
{{ article.desc }}
</div>
<div class="article-xia">
<a href="/bolg/{{ article.user.username }}"><span>{{ article.user.username }}</span></a> 发布于
<span>{{ article.create_time }}</span>
<span>点赞({{ article.up_count }})</span>
<span>评论({{ article.comment_count }})</span>
</div>
</div>
<hr>
</div>
{% endfor %}
</div>
<div class="col-md-2 ">
<div class="panel panel-info">
<div class="panel-heading">
<h3 class="panel-title">Panel title</h3>
</div>
<div class="panel-body">
Panel content
</div>
</div>
</div>

</div>
</div>

<script src="/static/jquery-3.3.1.min.js"></script>
<script src="/static/bootstrap-3.3.7/js/bootstrap.min.js"></script>
<script src="/static/setupAjax.js"></script>


</body>
</html>

———————————————————————————————————————————————————————————————————————————————

猜你喜欢

转载自www.cnblogs.com/yangli0504/p/9265048.html