BBS项目 个人界面分类,文章,模板的使用详解

forms.py

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("两次输入的密码不一样")

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

url1.py

 

"""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)),

]

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

url2.py

 

from django.conf.urls import url

from bolg import views

urlpatterns = [
#筛选取用户和id
url(r'(.*)/article/(\d+)/$', views.article_detail), # home(request, username)
#赛选取用户,类型,类型名
url(r'(.*)/(category|tag|data)/(.*)/$', views.home), # home(request, username)
#取用户
url(r'(.*)/$', views.home), # home(request, username)
]

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

views.py

 

def article_detail(request,username,article_id):
user_obj=models.UserInfo.objects.filter(username=username).first()
if user_obj:
blog=user_obj.blog
else:
return HttpResponse('404')
#取主键对应的文章
article_obj=models.Article.objects.filter(pk=article_id).first()

return render(request,'article_detail.html',{'blog':blog,
'username':username,
'article_obj':article_obj,
})

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

 

zuozhujian.py

 

from django import template

register = template.Library()

#inclusion_tag自定义,用于返回html代码片段,下面返回的就是zujian.html代码片段
@register.inclusion_tag('zujian.html')
def zuozhujian(username):
from django.db.models import Count
from bolg import models

user_obj = models.UserInfo.objects.filter(username=username).first()

# 外键的正向查询
# 对象直接点外键字段名,获取对象
blog_obj = user_obj.blog
# 先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.filter(user=user_obj).extra(
select={"time": "DATE_FORMAT(create_time, '%%Y-%%m')"}).values("time").annotate(
num=Count("nid")).values("time", "num")

return {
'username':username,
'category_list':category_list,
'tag_obj':tag_obj,
'date_list':date_list,
}

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

article_detail.py

 

#用了继承母版
{% extends 'base.html' %}
#block 替换母版内的代码
{% block page-main-zuo %}
#load 替换html代码片段
{% load zuozhujian %}

{% zuozhujian username %}
{% endblock %}

{% block page-main-you %}
#写文章界面
<div class="page-header">
<h1>{{ article_obj.title }}
<small></small>
</h1>
</div>
<div>
{{ article_obj.articledetail.content|safe }}
</div>


{% endblock %}

{% block page-css %}
{% endblock %}

{% block page-js %}
{% endblock %}

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

base.py

 

<!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 }}">
{# 填充css#}
{% block page-css %}

{% endblock %}
</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"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/bolg/{{ blog.userinfo.username }}"> {{ 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">
{# 填充左#}
{% block page-main-zuo %}
{% endblock %}

</div>
<div class="col-md-9">
{# 填充右#}
{% block page-main-you %}
{% endblock %}
</div>
</div>
</div>

{# js填充#}
{% block page-js %}

{% endblock %}

</body>
</html>

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

home.py

 

<!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"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/bolg/{{ blog.userinfo.username }}"> {{ 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="/bolg/{{ username }}/category/{{ category.title }}/"> {{ 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="/bolg/{{ username }}/tag/{{ tag.title }}/"> {{ 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="/bolg/{{ username }}/data/{{ data.time }}/"> {{ 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">
<a href="/bolg/{{ username }}/article/{{ article.nid }}/"><h2>{{ article.title }}</h2></a>
</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>

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

zhujian.py

 

<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="/bolg/{{ username }}/category/{{ category.title }}/"> {{ 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="/bolg/{{ username }}/tag/{{ tag.title }}/"> {{ 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="/bolg/{{ username }}/data/{{ data.time }}/"> {{ data.time }}({{ data.num }})</a></li>
{% endfor %}
</ul>
</div>
</div>

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

 

posted @ 2018-07-05 20:29  yangli0504  阅读(489)  评论(0编辑  收藏  举报