搭建自己的博客(二十一):通过django表单实现登录注册
1、变化的部分
aaarticlea/png;base64,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" alt="" />
2、上代码:
{# 引用模板 #}
{% extends 'base.html' %}
{% load staticfiles %}
{% block header_extends %}
<link rel="stylesheet" href="{% static 'blog/blog.css' %}">
{% endblock %}
{# 标题 #}
{% block title %}
{{ blog.title }}
{% endblock %}
{# 内容#}
{% block content %}
<div class="container">
<div class="row">
<div class="col-10 offset-1">
<ul class="blog-info-description">
<h3>{{ blog.title }}</h3>
<li>作者:{{ blog.author }}</li>
{# 时间过滤器让时间按照自己需要的格式过滤 #}
<li>发布日期:{{ blog.created_time|date:"Y-m-d H:n:s" }}</li>
<li>分类:
<a href="{% url 'blogs_with_type' blog.blog_type.pk %}">
{{ blog.blog_type }}
</a>
</li>
<li>阅读({{ blog.get_read_num }})</li>
</ul>
<p class="blog-content">{{ blog.content|safe }}</p>
<p>上一篇:
{% if previous_blog %}
<a href="{% url 'blog_detail' previous_blog.pk %}">{{ previous_blog.title }}</a>
{% else %}
<span>没有了</span>
{% endif %}
</p>
<p>下一篇:
{% if next_blog %}
<a href="{% url 'blog_detail' next_blog.pk %}">{{ next_blog.title }}</a>
{% else %}
<span>没有了</span>
{% endif %}
</p>
</div>
</div>
<div class="row">
<div class="col-10 offset-1">
<div class="comment-area">
<h3 class="comment-area-title">提交评论</h3>
{% if user.is_authenticated %}
<form action="{% url 'update_comment' %}" method="post" style="overflow: hidden">
{% csrf_token %}
<div class="form-group">
<label for="form-control">{{ user.username }},欢迎评论~</label>
<textarea class="form-control" name="text" id="comment_text" rows="4"></textarea>
</div>
<input type="hidden" name="object_id" value="{{ blog.pk }}">
<input type="hidden" name="content_type" value="blog">
<input type="submit" value="评论" class="btn btn-primary float-right">
</form>
{% else %}
您尚未登录,登录之后方可评论
{# 提交登录的时候带上从哪里访问的路径 #}
<a class="btn btn-primary" href="{% url 'login' %}?from={{ request.get_full_path }}">登录</a>
<span> or </span>
<a class="btn-danger btn" href="{% url 'register' %}?from={{ request.get_full_path }}">注册</a>
{% endif %}
</div>
<div class="-comment-area">
<h3 class="comment-area-title">评论列表</h3>
{% for comment in comments %}
<div>
{{ comment.user.username }}
{{ comment.comment_time|date:"Y-m-d H:n:s" }}
{{ comment.text }}
</div>
{% empty %}
{% endfor %}
</div>
</div>
</div>
</div>
{% endblock %}
{% block js %}
<script>
$(".nav-blog").addClass("active").siblings().removeClass("active");
</script>
{% endblock %}
blog_detail.html
# -*- coding: utf-8 -*-
# @Time : 18-11-20 下午8:10
# @Author : Felix Wang from django import forms
from django.contrib import auth
from django.contrib.auth.models import User class LoginForm(forms.Form):
username = forms.CharField(label='用户名', required=True,
widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': '请输入用户名'}))
# widget指定input标签类型
password = forms.CharField(label='密码',
widget=forms.PasswordInput(attrs={'class': 'form-control', 'placeholder': '请输入密码'})) def clean(self): # 验证数据
username = self.cleaned_data['username']
password = self.cleaned_data['password']
user = auth.authenticate(username=username, password=password)
if user is None:
raise forms.ValidationError('用户名或密码错误')
self.cleaned_data.user = user # 将验证过的user放入clean_data
return self.cleaned_data class RegisterForm(forms.Form):
# 用户名字段
username = forms.CharField(label='用户名',
max_length=30,
min_length=3,
required=True,
widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': '请输入用户名'}))
# 邮箱字段
email = forms.EmailField(label='邮箱',
min_length=3,
required=True,
widget=forms.EmailInput(attrs={'class': 'form-control', 'placeholder': '请输入邮箱'}))
# 密码字段
password = forms.CharField(label='密码',
min_length=6,
required=True,
widget=forms.PasswordInput(
attrs={'class': 'form-control', 'placeholder': '请输入密码'}))
# 再次输入密码
password_again = forms.CharField(label='确认密码',
min_length=6,
required=True,
widget=forms.PasswordInput(
attrs={'class': 'form-control', 'placeholder': '请再输入一次密码'})) def clean_username(self):
username = self.cleaned_data['username']
if User.objects.filter(username=username).exists():
raise forms.ValidationError('用户名已存在')
return username def clean_email(self):
email = self.cleaned_data['email']
if User.objects.filter(email=email).exists():
raise forms.ValidationError('邮箱已存在') return email def clean_password_again(self):
password = self.cleaned_data['password']
password_again = self.cleaned_data['password_again']
if password != password_again:
raise forms.ValidationError('两次输入的密码不一致')
return password_again
forms.py
"""myblog URL Configuration The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/2.1/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
from . import views urlpatterns = [
path('', views.home, name='home'), # 主页路径
path('admin/', admin.site.urls),
path('ckeditor', include('ckeditor_uploader.urls')), # 配置上传url
path('blog/', include('blog.urls')), # 博客app路径
path('comment/', include('comment.urls')), # 博客app路径
path('login/', views.login, name='login'), # 登录
path('register/', views.register, name='register'), # 登录
] # 设置ckeditor的上传
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
urls.py
# -*- coding: utf-8 -*-
# @Time : 18-11-7 下午4:12
# @Author : Felix Wang from django.shortcuts import render, redirect
from django.contrib.contenttypes.models import ContentType
from django.contrib import auth
from django.contrib.auth.models import User
from django.urls import reverse
from read_statistics.utils import get_seven_days_read_data, get_x_days_hot_data
from blog.models import Blog
from .forms import LoginForm, RegisterForm def home(requests):
blog_content_type = ContentType.objects.get_for_model(Blog)
dates, read_nums = get_seven_days_read_data(blog_content_type) context = {
'read_nums': read_nums,
'dates': dates,
'today_hot_data': get_x_days_hot_data(0), # 获取今日热门
'yesterday_hot_data': get_x_days_hot_data(1), # 获取昨日热门
'seven_days_hot_data': get_x_days_hot_data(7), # 获取周热门
'one_month_hot_data': get_x_days_hot_data(30), # 获取月热门
}
return render(requests, 'home.html', context) def login(requests):
# 如果是form表单提交验证登录
if requests.method == 'POST':
login_form = LoginForm(requests.POST)
if login_form.is_valid(): # 验证是否通过
# 因为在form表单验证过了,所以不用自己再验证
user = login_form.cleaned_data.get('user')
auth.login(requests, user)
return redirect(requests.GET.get('from', reverse('home')))
else:
login_form.add_error(None, '用户名或密码不正确')
else:
login_form = LoginForm()
context = {
'login_form': login_form,
}
return render(requests, 'login.html', context) def register(requests):
if requests.method == 'POST':
reg_form = RegisterForm(requests.POST)
if reg_form.is_valid():
username = reg_form.cleaned_data['username']
email = reg_form.cleaned_data['email']
password = reg_form.cleaned_data['password'] # 创建用户
user = User.objects.create_user(username=username, email=email, password=password)
user.save() # 登录用户
user = auth.authenticate(username=username, password=password)
auth.login(requests, user)
# 登录之后跳转
return redirect(requests.GET.get('from', reverse('home')))
else:
reg_form = RegisterForm() context = {
'reg_form': reg_form,
}
return render(requests, 'register.html', context)
mylog下的views.py
{% extends 'base.html' %}
{% load staticfiles %}
{% block title %}
我的博客|登录
{% endblock %}
{% block content %}
<div class="container">
<div class="col-xl-6 offset-xl-3">
<div class="card">
<h5 class="card-header">登录</h5>
<div class="card-body">
<form action="{% url 'login' %}" method="post">
{% csrf_token %}
{% for field in login_form %}
<label for="{{ field.id_for_label }}">{{ field.label }}</label>
{{ field }}
<p class="text-danger">{{ field.errors.as_text }}</p>
{% endfor %}
<span class="text-danger float-left">{{ login_form.non_field_errors }}</span>
<input type="submit" value="登录" class="btn btn-primary float-right">
</form>
</div>
</div>
</div>
</div>
{% endblock %}
{% block js %}
{# 将首页这个按钮设置激活状态 #}
<script>
$(".nav-home").addClass("active").siblings().removeClass("active");
</script>
{% endblock %}
login.html
{% extends 'base.html' %}
{% load staticfiles %}
{% block title %}
我的博客|登录
{% endblock %}
{% block content %}
<div class="container">
<div class="col-xl-6 offset-xl-3">
<div class="card">
<h5 class="card-header">登录</h5>
<div class="card-body">
<form action="{% url 'login' %}" method="post">
{% csrf_token %}
{% for field in login_form %}
<label for="{{ field.id_for_label }}">{{ field.label }}</label>
{{ field }}
<p class="text-danger">{{ field.errors.as_text }}</p>
{% endfor %}
<span class="text-danger float-left">{{ login_form.non_field_errors }}</span>
<input type="submit" value="登录" class="btn btn-primary float-right">
</form>
</div>
</div>
</div>
</div>
{% endblock %}
{% block js %}
{# 将首页这个按钮设置激活状态 #}
<script>
$(".nav-home").addClass("active").siblings().removeClass("active");
</script>
{% endblock %}
register.html
搭建自己的博客(二十一):通过django表单实现登录注册的更多相关文章
- 一站式搭建 GitHub Pages 博客 (一)
本文将详细讲解如何快速搭建 GitHub Pages 博客页面 关于博客主题,博客信息更改,上传文章等将会在 一站式搭建 GitHub Pages 博客 (二) 中进行详细讲解 准备阶段 注册 Git ...
- 基于hexo+github搭建一个独立博客
一直听说用hexo搭建一个拥有自己域名的博客是很酷炫的事情~,在这十一花上半个小时整个hexo博客岂不美哉. 使用Hexo吸引我的是,其简单优雅, 而且风格多变, 适合程序员搭建个人博客,而且支持多平 ...
- 一步步搭建自己的博客 .NET版(2、评论功能)
前言 这次开发的博客主要功能或特点: 第一:可以兼容各终端,特别是手机端. 第二:到时会用到大量html5,炫啊. 第三:导入博客园的精华文章,并做分类.(不要封我) 第四:做 ...
- 2015年12月12 Node.js实战(一)使用Express+MongoDB搭建多人博客
序,Node是基于V8引擎的服务器端脚本语言. 基础准备 Node.js: Express:本文用的是3.21.2版本,目前最新版本为4.13.3,Express4和Express3还是有较大区别,可 ...
- 如何搭建一个独立博客——简明Github Pages与Hexo教程
摘要:这是一篇很详尽的独立博客搭建教程,里面介绍了域名注册.DNS设置.github和Hexo设置等过程,这是我写得最长的一篇教程.我想将我搭建独立博客的过程在一篇文章中尽可能详细地写出来,希望能给后 ...
- Go语言搭建自己的博客
我是如何用Go语言搭建自己的博客的 前言: 话说,已经很久没有在博客园更新博客了,之前写的关于go语言的系列学习文章<让我们一起Go>也由于种种原因一度中断.但是,正如我之前在文章中所 ...
- github+hexo搭建自己的博客网站(六)进阶配置(搜索引擎收录,优化你的url)
详细的可以查看hexo博客的演示:https://saucxs.github.io/ 绑定了域名: http://www.chengxinsong.cn hexo+github博客网站源码(可以clo ...
- github+hexo搭建自己的博客网站(七)注意事项(避免read.me,CNAME文件的覆盖,手动改github page的域名)
详细的可以查看hexo博客的演示:https://saucxs.github.io/ 绑定域名可以查看:http://www.chengxinsong.cn 可以查看在github上生成的静态文件(如 ...
- Django 系列博客(十一)
Django 系列博客(十一) 前言 本篇博客介绍使用 ORM 来进行多表的操作,当然重点在查询方面. 创建表 实例: 作者模型:一个作者有姓名和年龄. 作者详细模型:把作者的详情放到详情表,包含生日 ...
随机推荐
- Vue使用指南(三)
组件 '''1.根组件:new Vue()创建的组件,一般不明确自身的模板,模板就采用挂载点2.局部组件: local_component = {}2.全局组件: Vue.component({})' ...
- C#方法(用法,参数)
方法:是一种用于实现可以由对象或类执行的计算或操作的成员,是一个已命名的语句集.方法就是把一些相关的语句组织到一起,用来执行一个任务的语句块.比如每个C#程序至少带一个main函数 1.格式:修饰符 ...
- c# 事件 +=和-=有什么区别
+=就是發生新事件的同時通知你: -=就是發生新事件的同時不通知你:
- 3_PHP表达式_4_PHP运算符
以下为学习孔祥盛主编的<PHP编程基础与实例教程>(第二版)所做的笔记. 3.4.1 算术运算符 <?php $num1 = -10; $num2 = -4; $num3 = $nu ...
- 远程 Linux(Ubuntu 18)添加字体
安装 xshell与xftp 连接xshell 点击 xshell上方工具栏中的xftp图标, 自动连接xftp linux下创建字体目录 su cd / cd usr/share/fonts mkd ...
- Node.js 实战(一)之—优化汇总
Express 页面缓存 app.set("cache view",true); --设置页面缓存 开发模式下博主建议不要这么做,因为开发中我们会频繁的对页面的样式.js等进行修改 ...
- SQL SERVER-LinkServer搬迁
选中linkserver,按F7打开对象游览器, 选中linkserver,生成脚本. 把密码填入脚本运行即可 USE [master] GO /****** Object: LinkedServer ...
- Python基础Day6
一.代码块 一个模块(模块就是py文件),一个函数,一个类,一个文件都是一个代码块,一个整体是一个代码块. 交互模式的每一行都是一个代码块(交互模式:命令提示符),相当于每行都在不同的文件 二.id ...
- SQL注入是什么?如何防止?
SQL注入是什么?如何防止? SQL注入是一种注入攻击,可以执行恶意SQL语句.下面本篇文章就来带大家了解一下SQL注入,简单介绍一下防止SQL注入攻击的方法,希望对大家有所帮助. 什么是SQL注入? ...
- seo域名选择
1-1第一选域名: 1,简单好记,有意义. 2,后缀首选com 其次cn 1-2购买域名网站有 1,阿里云 2,godaddy 3 ,景安 购买是可以在这三个域名平台都看看价格有些不一样.(可以省钱) ...