forms.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from django.forms import Form,fields,widgets
from django.core.exceptions import ValidationError
from blog import models
from django.contrib.auth.models import User
from django.http import HttpRequest
from django.views import View
class LoginForm(Form):
username = fields.CharField(
min_length=2,
max_length=16,
required=True,
label="用户名:",
initial="test",
widget=widgets.TextInput(
attrs={"class": "form-control"}
),
error_messages={
"required": "不能为空",
"invalid": "格式错误",
"min_length": "用户名最短2位"
}
)
password = fields.CharField(
min_length=2,
max_length=16,
required=True,
label="密码:",
initial="123",
widget=widgets.TextInput(
attrs={"class": "form-control", "type": "password"}
),
error_messages={
"required": "不能为空",
"invalid": "格式错误",
"min_length": "密码最短2位"
}
)
class RegForm(Form):
username = fields.CharField(
min_length=2,
max_length=16,
required=True,
label="用户名:",
widget=widgets.TextInput(
attrs={"class": "form-control"}
),
error_messages={
"required": "不能为空",
"invalid": "格式错误",
"min_length": "用户名最短2位"
}
)
password = fields.CharField(
min_length=2,
max_length=16,
required=True,
label="密码:",
widget=widgets.TextInput(
attrs={"class": "form-control"}
),
error_messages={
"required": "不能为空",
"invalid": "格式错误",
"min_length": "密码最短2位"
}
)
email = fields.EmailField(
label="email:",
widget=widgets.TextInput(
attrs={"class": "form-control"}
),
error_messages={
"required": "不能为空",
"invalid": "格式错误",
}
)
def clean_username(self):
reg_name = self.cleaned_data.get("username")
if models.UserInfo.objects.filter(username=reg_name):
self.add_error("username", ValidationError("用户名已存在"))
else:
return reg_name
def clean_email(self):
reg_email = self.cleaned_data.get("email")
if models.UserInfo.objects.filter(email=reg_email):
self.add_error("email", ValidationError("邮箱已注册"))
else:
return reg_email
class SetpwdForm(Form):
old_password = fields.CharField(
min_length=2,
max_length=16,
required=True,
label="旧密码:",
widget=widgets.TextInput(
attrs={"class": "form-control"}
),
error_messages={
"required": "不能为空",
"invalid": "格式错误",
"min_length": "用户名最短2位"
}
)
new_password = fields.CharField(
min_length=2,
max_length=16,
required=True,
label="新密码:",
widget=widgets.TextInput(
attrs={"class": "form-control"}
),
error_messages={
"required": "不能为空",
"invalid": "格式错误",
"min_length": "用户名最短2位"
}
)
repeat_password = fields.CharField(
min_length=2,
max_length=16,
required=True,
label="重复密码:",
widget=widgets.TextInput(
attrs={"class": "form-control"}
),
error_messages={
"required": "不能为空",
"invalid": "格式错误",
"min_length": "用户名最短2位"
}
)
def clean(self):
pwd = self.cleaned_data.get("new_password")
re_pwd = self.cleaned_data.get("repeat_password")
if pwd != re_pwd:
self.add_error("repeat_password", ValidationError("两次密码不一致"))
else:
return self.cleaned_data
class SetInfoForm(Form):
email = fields.EmailField(
label="email:",
initial="",
widget=widgets.TextInput(
attrs={"class": "form-control"}
),
error_messages={
"required": "不能为空",
"invalid": "格式错误",
}
)
# pic = fields.ImageField(
# label="头像:",
# widget=widgets.FileInput(
# attrs={"class": "form-control"}
# ),
# error_messages={
# "required": "不能为空",
# }
# )
views.py
def login(request):
error_msg = ""
if request.method == "GET":
Form_obj = LoginForm()
return render(request, "login.html", {"Form_obj": Form_obj})
if request.method == "POST":
Form_obj = LoginForm(request.POST)
if Form_obj.is_valid():
user = auth.authenticate(**Form_obj.cleaned_data)
if user:
auth.login(request, user)
request.session["is_login"] = "1"
return redirect('/index/')
else:
error_msg = "用户名或密码错误"
return render(request,"login.html",{"error_msg": error_msg,"Form_obj": Form_obj})
def logout(request):
auth.logout(request)
return redirect('/login/')
def register(request):
if request.method == "GET":
reg_obj = RegForm()
return render(request, "register.html", {"reg_obj": reg_obj})
else:
ret = {"status": 0, "msg": ""}
reg_obj = RegForm(request.POST, request.FILES)
if reg_obj.is_valid():
# file = reg_obj.cleaned_data["pic"]
# with open(f"pics/{file.name}", "wb") as f:
# for chunk in file.chunks():
# f.write(chunk)
models.UserInfo.objects.create_user(**reg_obj.cleaned_data)
ret["msg"] = "/index/"
return JsonResponse(ret)
else:
ret["status"] = 1
ret["msg"] = reg_obj.errors
return JsonResponse(ret)
# return render(request, "register.html", {"reg_obj": reg_obj, "error_msg": error_msg})
def check_username(request):
ret = {"status": 0, "msg": ""}
username = request.GET.get("username")
if models.UserInfo.objects.filter(username=username):
ret["status"] = 1
ret["msg"] = "用户名已存在"
return JsonResponse(ret)
@login_required
def change_pwd(request):
if request.method == "GET":
setpwd_obj = SetpwdForm()
return render(request, "set_password.html", {"setpwd_obj": setpwd_obj})
if request.method == "POST":
error_msg = ""
user = request.user
setpwd_obj = SetpwdForm(request.POST)
if setpwd_obj.is_valid():
old_password = setpwd_obj.cleaned_data.get("old_password")
new_password = setpwd_obj.cleaned_data.get("new_password")
repeat_password = setpwd_obj.cleaned_data.get("repeat_password")
if not user.check_password(old_password):
error_msg = "旧密码错误"
else:
if new_password != repeat_password:
error_msg = "密码不一致"
elif new_password == old_password:
error_msg = "新密码不能和旧密码重复"
else:
user.set_password(repeat_password)
user.save()
return redirect("/login/")
return render(request,"set_password.html", {"setpwd_obj": setpwd_obj, "error_msg": error_msg})
@login_required
def set_info(request):
if request.method == "GET":
SetInfo_obj = SetInfoForm()
return render(request, "set_info.html", {"SetInfo_obj": SetInfo_obj})
else:
SetInfo_obj = SetInfoForm(request.POST)
avatar_img = request.FILES.get("pic")
if SetInfo_obj.is_valid():
file_path = os.path.join(settings.MEDIA_ROOT, avatar_img.name)
if os.path.exists(file_path):
fix = datetime.now().strftime('%Y%m%d%H%M%S')
file_path = os.path.join(settings.MEDIA_ROOT, fix + avatar_img.name)
else:
fix = ""
with open(file_path, "wb") as f:
for chunk in avatar_img.chunks():
f.write(chunk)
models.UserInfo.objects.filter(username=request.user.username).update(**SetInfo_obj.cleaned_data, pic=(fix+avatar_img.name))
return redirect("/index/")
else:
return render(request, "set_info.html", {"SetInfo_obj": SetInfo_obj})
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>注册</title>
{% include "common/css.html" %}
</head>
<body>
{% include "common/navbar.html" %}
<div class="container">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<div class="panel panel-primary top-from">
<div class="panel-heading">注册</div>
<div class="panel-body">
<form action="/register/" method="post" novalidate autocomplete="off" class="form-horizontal" enctype="multipart/form-data">
{% csrf_token %}
{% for obj in reg_obj %}
{% if obj.name != "pic" %}
<div class="form-group">
<label for="{{ obj.id_for_label }}"
class="col-sm-3 control-label">{{ obj.label }}</label>
<div class="col-sm-6">
{{ obj }}
<span class="help-block"> {{ obj.errors.0 }} </span>
</div>
</div>
{% endif %}
{% endfor %}
<div class="form-group">
<label class="col-sm-3 control-label">头像:</label>
<div class="col-sm-6">
<label for="id_pic">
<img class="pic" id="pic-img" src="/static/img/default.png" alt=""></label>
<input accept="image/*" style="display: none" type="file" name="pic" id="id_pic">
<span class="help-block"></span>
</div>
</div>
<div class="form-group">
<div class="col-sm-9 col-sm-offset-3">
<button type="button" class="btn btn-default" id="reg-submit">注册</button>
<span class="help-block"> {{ error_msg }} </span>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<script src="/static/jquery-3.4.1.min.js" ></script>
<script>
{#头像绑定事件#}
$("#id_pic").change(function () {
{#创建一个读取文件对象#}
var fileReader = new FileReader();
{#取到该文件#}
console.log(this.files[0]);
{#读取该文件#}
fileReader.readAsDataURL(this.files[0]);
fileReader.onload = function(){
{#文件读取完后加载到img标签#}
$("#pic-img").attr("src",fileReader.result);
};
});
{#// AJAX提交注册的数据#}
$("#reg-submit").click(function () {
var formData = new FormData();
formData.append("username", $("#id_username").val());
formData.append("password", $("#id_password").val());
formData.append("email", $("#id_email").val());
formData.append("pic", $("#id_pic")[0].files[0]);
formData.append("csrfmiddlewaretoken", $("[name='csrfmiddlewaretoken']").val());
$.ajax({
url: "/register/",
type: "post",
{#ajax传文件加参数#}
processData: false,
contentType: false,
data: formData,
success:function (data) {
if (data.status){
{# 有错误就展示错误#}
{#// console.log(data.msg);#}
{#// 将报错信息填写到页面上#}
$.each(data.msg, function (k,v) {
// console.log("id_"+k, v[0]);
// console.log($("#id_"+k));
$("#id_"+k).next("span").text(v[0]).parent().parent().addClass("has-error");
})
}else {
location.href = data.msg;
}
}
})
});
{#// 将所有的input框绑定获取焦点的事件,将所有的错误信息清空#}
$("form input").focus(function () {
$(this).next().text("").parent().parent().removeClass("has-error");
});
{#$("#id_username").blur(function () {#}
$("#id_username").on("input", function () {
var username = $(this).val();
$.ajax({
url: "/check_username/",
type: "get",
data: {"username": username},
success: function(data){
if (data.status){
$("#id_username").next().text(data.msg).parent().parent().addClass("has-error");
}else{
$("#id_username").next().parent().parent().removeClass("has-error");
}
}
})
})
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>修改个人信息</title>
{% include "common/css.html" %}
</head>
<body>
{% include "common/navbar.html" %}
<div class="container">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<div class="panel panel-primary top-from">
<div class="panel-heading">修改个人信息</div>
<div class="panel-body">
<form action="/set_info/" method="post" novalidate autocomplete="off" class="form-horizontal" enctype="multipart/form-data">
{% csrf_token %}
{% for obj in SetInfo_obj %}
{% if obj.name != "pic" %}
<div class="form-group">
<label for="{{ obj.id_for_label }}"
class="col-sm-3 control-label">{{ obj.label }}</label>
<div class="col-sm-6">
{{ obj }}
<span class="help-block"> {{ obj.errors.0 }} </span>
</div>
</div>
{% endif %}
{% endfor %}
<div class="form-group">
<label class="col-sm-3 control-label">头像:</label>
<div class="col-sm-6">
<label for="id_pic">
<img class="pic" id="pic-img" src="/media/{{ request.user.pic }}" alt="..."></label>
<input accept="image/*" value="/media/{{ request.user.pic }}" style="display: none" type="file" name="pic" id="id_pic">
<span class="help-block">{{ SetInfo_obj.errors.pic.0 }}</span>
</div>
</div>
<div class="form-group">
<div class="col-sm-9 col-sm-offset-3">
<button type="submit" class="btn btn-default" id="reg-submit">提交</button>
<span class="help-block"> {{ error_msg }} </span>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<script>
$("#id_pic").change(function(){
var fileReader = new FileReader();
console.log(this.files[0]);
fileReader.readAsDataURL(this.files[0]);
fileReader.onload = function () {
$("#pic-img").attr("src",fileReader.result);
};
});
</script>
</body>
</html>
set_info
{% include “common/navbar.html” %}
修改密码
<form action="/change_pwd/" method="post" novalidate autocomplete="off" class="form-horizontal">
{% csrf_token %}
{% for obj in setpwd_obj %}
<div class="form-group">
<label for="{{ obj.id_for_label }}"
class="col-sm-3 control-label">{{ obj.label }}</label>
<div class="col-sm-6">
{{ obj }}
<span class="help-block"> {{ obj.errors.0 }} </span>
</div>
</div>
{% endfor %}
<div class="form-group">
<div class="col-sm-offset-3 col-sm-6">
<button type="submit" class="btn btn-default">提交</button>
<span class="help-block"> {{ error_msg }} </span>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
set_password