BBS项目 注册界面and部分首页代码详解
forms
# 创建注册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
from django.conf.urls import url
from django.contrib import admin
from bolg import views
from django.views.static import serve
from django.conf import settings
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})
]
———————————————————————————————————————————————————————————————————————————————
views
# 注册界面
def reg(request):
reg_obj = forms.RegForm()
if request.method == "POST":
# 加判断
ret = {'code': 0}
# 传值创建对象
reg_obj = forms.RegForm(request.POST)
# 用is_valid验证数据有没有问题
if reg_obj.is_valid():
# 取出头像图片文件
avatar_obj = request.FILES.get('avatar')
# 把数据re_password取出,因为表中没有re_password这个字段,只是用来验证
reg_obj.cleaned_data.pop('re_password')
# 创建添加用户
models.UserInfo.objects.create_user(
# 添加字段对应的值
avatar=avatar_obj,
# 打散字典,值已被cleaned_data转成字符串
**reg_obj.cleaned_data
)
ret['data'] = '/index/'
else:
ret['code'] = 1
# 把reg_obj返回的错误数据放入
ret['data'] = reg_obj.errors
return JsonResponse(ret)
return render(request, 'reg.html', {'reg_obj': reg_obj})
#注销
#用 auth.logout(request) 将当前请求的session信息会全部清除
def zhuxiao(request):
auth.logout(request)
return redirect('/index/')
#主界面
def index(request):
#is_authenticated判断是否以登录,登录时必须在login存参数,否则无法生效
if request.user.is_authenticated():
#取出用户名
usernmae=request.user.username
#根据用户名拿对象
user_obj=models.UserInfo.objects.filter(username=usernmae)
#把对象传递进去
return render(request, 'index.html',{"user_obj":user_obj})
return render(request, 'index.html',{"user_obj":''})
———————————————————————————————————————————————————————————————————————————————
html-reg
<!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">
<style>
#img_tou {
width: 80px;
height: 80px;
}
#ding{
margin-top: 120px;
}
</style>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-6 col-md-offset-3 "id="ding">
{# 面板开始#}
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">BBS注册界面</h3>
</div>
<div class="panel-body">
{# 注册界面开始#}
<form class="form-horizontal" autocomplete="off" novalidate>
<div class="form-group">
<label for="{{ reg_obj.username.id_for_label }}"
class="col-sm-2 control-label">{{ reg_obj.username.label }}</label>
<div class="col-sm-10">
{{ reg_obj.username }}
<span class="help-block"></span>
</div>
</div>
<div class="form-group">
<label for="{{ reg_obj.password.id_for_label }}"
class="col-sm-2 control-label">{{ reg_obj.password.label }}</label>
<div class="col-sm-10">
{{ reg_obj.password }}
<span class="help-block"></span>
</div>
</div>
<div class="form-group">
<label for="{{ reg_obj.re_password.id_for_label }}"
class="col-sm-2 control-label">{{ reg_obj.re_password.label }}</label>
<div class="col-sm-10">
{{ reg_obj.re_password }}
<span class="help-block"></span>
</div>
</div>
<div class="form-group">
<label for="{{ reg_obj.phone.id_for_label }}"
class="col-sm-2 control-label">{{ reg_obj.phone.label }}</label>
<div class="col-sm-10">
{{ reg_obj.phone }}
<span class="help-block"></span>
</div>
</div>
<div class="form-group">
<label for=""
class="col-sm-2 control-label">头像</label>
<div class="col-sm-10">
<input accept="image/*" type="file" id="touxiang" name="avatar" style="display: none">
<label for="touxiang"><img id="img_tou" src="/static/img/default.png" alt=""></label>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button id="zhuche" type="button" class="btn btn-default">注册</button>
</div>
</div>
</form>
{# 注册界面结束#}
</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>
<script>
$('#zhuche').click(function () {
//创建表单对象
var data_obj = new FormData();
//把上面用户输入的所有值都添加进去
data_obj.append("username", $('#id_username').val());
data_obj.append("password", $('#id_password').val());
data_obj.append("phone", $('#id_phone').val());
data_obj.append("re_password", $('#id_re_password').val());
data_obj.append("avatar", $('#touxiang')[0].files[0]);
$.ajax({
url: "/reg/",
type: 'post',
processData: false,
contentType: false,
data: data_obj,
success: function (data) {
if (data.code) {
//创建变量接收错误信息
var cuowu = data.data;
//用each方法取出所有的k,v
$.each(cuowu, function (k, v) {
// k: 字段名 v:报错信息的数组
// 根据字段名找对应的input标签,把错误信息添加到对应位置
//遍历.help-block类,将值改成对应的v,然后再找关系颜色的那个类,将其改为警告红色
$("#id_" + k).next(".help-block").text(v[0]).parent().parent().addClass("has-error");
})
} else {
location.href = data.data || "/login/"
}
}
})
});
//找到form 下的input框 加点击事件,点击后用next找到span标签,修改其text值,删除警告色
$('form input').click(function () {
$(this).next(".help-block").text("").parent().parent().removeClass("has-error");
});
$('#touxiang').change(function () {
// 找到你选中的那个头像文件
var fileObj = this.files[0];
// 读取文件路径
var fileReader = new FileReader();
fileReader.readAsDataURL(fileObj);
// 等图片被读取完毕之后,再做后续操作
fileReader.onload = function () {
// 设置预览图片
$("#img_tou").attr("src", fileReader.result);
};
})
</script>
</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">
<style>
#img_tou {
width: 40px;
height: 40px;
margin-top: 5px;
}
</style>
</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="#">Brand</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="#">Link <span class="sr-only">(current)</span></a></li>
<li><a href="#">Link</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
aria-expanded="false">Dropdown <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="#">Separated link</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">One more separated link</a></li>
</ul>
</li>
</ul>
<form class="navbar-form navbar-left">
<div class="form-group">
<input type="text" class="form-control" placeholder="Search">
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
<ul class="nav navbar-nav navbar-right">
{# 判断传来的是否有对象,有就调用对象里的值,没有就登录注册#}
{% if user_obj %}
{# 调用对象里的值进行操作#}
<li><img id="img_tou" src="/media/{{ request.user.avatar }}" alt=""></li>
<li><a href="#">{{ request.user.username }}</a></li>
<li><a href="/zhuxiao/">注销</a></li>
{% else %}
<li><a href="/login/">登录</a></li>
<li><a href="/reg/">注册</a></li>
{% endif %}
{# <li>{% if user_obj %}<a href="#">{{ user_obj.username }}</a>{% else %}<a href="/login/">登录</a>{% endif %}</li>#}
{# <li class="dropdown">#}
{# <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"#}
{# aria-expanded="false">Dropdown <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="#">Separated link</a></li>#}
{# </ul>#}
{# </li>#}
</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 "></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>
———————————————————————————————————————————————————————————————————————————————