项目主要模块
| 模块 | 功能 |
|---|---|
| 注册 | 图形验证、短信验证 |
| 登录 | 状态保持、Cookie、Session |
| 个人中心 | 图片上传、更新数据 |
| 发布博客 | 数据入库 |
| 博客首页 | 数据分页 |
| 博客详情 | 博客详情数据展示、评论功能 |
项目环境:
创建项目:
django-admin startproject djangoBlong
配置mysql
pip install PyMySQL
settings.py
DATABASES = {'default': {'ENGINE': 'django.db.backends.mysql', # 数据库引擎'HOST': '127.0.0.1', # 数据库主机'PORT': 3306, # 数据库端口'USER': 'root', # 数据库用户名'PASSWORD': '123456', # 数据库用户密码'NAME': 'blog' # 数据库名字},}
init.py文件中,添加如下代码
import pymysqlpymysql.install_as_MySQLdb()
配置Redis
pip install django-redis
settings.py文件末尾添加
CACHES = {"default": { # 默认"BACKEND": "django_redis.cache.RedisCache","LOCATION": "redis://127.0.0.1:6379/0","OPTIONS": {"CLIENT_CLASS": "django_redis.client.DefaultClient",}},"session": { # session"BACKEND": "django_redis.cache.RedisCache","LOCATION": "redis://127.0.0.1:6379/1","OPTIONS": {"CLIENT_CLASS": "django_redis.client.DefaultClient",}},}SESSION_ENGINE = "django.contrib.sessions.backends.cache"SESSION_CACHE_ALIAS = "session"
default:
- 默认的Redis配置项,采用0号Redis库。
session:
- 状态保持的Redis配置项,采用1号Redis库。
SESSION_ENGINE
- 修改session存储机制使用Redis保存。
SESSION_CACHE_ALIAS:
使用名为”session”的Redis配置项存储session数据。
配置日志
settings.py文件末尾添加
import osLOGGING = {'version': 1,'disable_existing_loggers': False, # 是否禁用已经存在的日志器'formatters': { # 日志信息显示的格式'verbose': {'format': '%(levelname)s %(asctime)s %(module)s %(lineno)d %(message)s'},'simple': {'format': '%(levelname)s %(module)s %(lineno)d %(message)s'},},'filters': { # 对日志进行过滤'require_debug_true': { # django在debug模式下才输出日志'()': 'django.utils.log.RequireDebugTrue',},},'handlers': { # 日志处理方法'console': { # 向终端中输出日志'level': 'INFO','filters': ['require_debug_true'],'class': 'logging.StreamHandler','formatter': 'simple'},'file': { # 向文件中输出日志'level': 'INFO','class': 'logging.handlers.RotatingFileHandler','filename': os.path.join(BASE_DIR, 'logs/blog.log'), # 日志文件的位置'maxBytes': 300 * 1024 * 1024,'backupCount': 10,'formatter': 'verbose'},},'loggers': { # 日志器'django': { # 定义了一个名为django的日志器'handlers': ['console', 'file'], # 可以同时向终端与文件中输出日志'propagate': True, # 是否继续传递日志信息'level': 'INFO', # 日志器接收的最低日志级别},}}
创建日志目录:

日志记录器的使用
不同的应用程序所定义的日志等级可能会有所差别,分的详细点的会包含以下几个等级:FATAL/CRITICAL = 重大的,危险的
- ERROR = 错误
- WARNING = 警告
- INFO = 信息
- DEBUG = 调试
- NOTSET = 没有设置 ```python import logging
创建日志记录器
logger = logging.getLogger(‘django’)
输出日志
logger.debug(‘测试logging模块debug’) logger.info(‘测试logging模块info’) logger.error(‘测试logging模块error’)
<a name="koQ9u"></a>## 静态资源文件项目根目录创建static文件。<br />指定静态文件加载路径```pythonSTATIC_URL = '/static/'# 配置静态文件加载路径STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]
配置模板
一、功能-注册
创建用户模块应用
python manage.py startapp users
注册用户模块
#主应用中的settings.pyINSTALLED_APPS = [...'users.apps.UsersConfig',]
创建模型
1.Django默认用户认证系统
- Django自带用户认证系统
- 它处理用户账号、组、权限以及基于cookie的用户会话。
- Django认证系统位置
- django.contrib.auth包含认证框架的核心和默认的模型。
- Django认证系统同时处理认证和授权
- 认证:验证一个用户是否它声称的那个人,可用于账号登录。
- 授权:授权决定一个通过了认证的用户被允许做什么。
Django认证系统包含的内容
Django认证系统中提供了用户模型类User保存用户的数据。
- User对象是认证系统的核心。
Django认证系统用户模型类位置
django.contrib.auth.models.User

父类AbstractUser介绍
User对象基本属性
- 创建用户必选:username、password
- 创建用户可选:email、first_name、last_name、last_login、date_joined、is_active 、is_staff、is_superuse
- 判断用户是否通过认证:is_authenticated
- USERNAME_FIELD:可以修改用户名认证字段
创建用户的方法
user = User.objects.create_user(username, password, **extra_fields)
用户认证的方法
from django.contrib.auth import authenticateuser = authenticate(username=username, password=password, **kwargs)
处理密码的方法
继承自AbstractUser(可通过阅读Django默认用户模型类的源码得知) 。
- 新增手机号字段,头像字段和简介字段。 ```python from django.db import models from django.contrib.auth.models import AbstractUser
用户信息
class User(AbstractUser):
# 电话号码字段# unique 为唯一性字段mobile = models.CharField(max_length=20, unique=True, blank=True)# 头像# upload_to为保存到响应的子目录中avatar = models.ImageField(upload_to='avatar/%Y%m%d/', blank=True)# 个人简介user_desc = models.TextField(max_length=500, blank=True)# 修改认证的字段USERNAME_FIELD = 'mobile'# 创建超级管理员的需要必须输入的字段REQUIRED_FIELDS = ['username', 'email']# 内部类 class Meta 用于给 model 定义元数据class Meta:db_table = 'tb_user' # 修改默认的表名verbose_name = '用户信息' # Admin后台显示verbose_name_plural = verbose_name # Admin后台显示def __str__(self):return self.mobile
<a name="i7AXb"></a>
### 4. 指定用户模型类
> 思考:为什么Django默认用户模型类是User?
> - 阅读源代码:'django.conf.global_settings’
> - AUTH_USER_MODEL = 'auth.User'
>
结论:
> - Django用户模型类是通过全局配置项
> - **AUTH_USER_MODEL**决定的
>
配置规则:
> AUTH_USER_MODEL = '应用名.模型类名'
配置文件中指定本项目用户模型类
```python
AUTH_USER_MODEL = 'users.User'
5.迁移用户模型类
#创建迁移文件
python manage.py makemigrations
#执行迁移文件
python manage.py migrate
创建视图
在users.views.py文件中定义视图
from django.views import View
class RegisterView(View):
"""用户注册"""
def get(self, request):
"""
提供注册界面
:param request: 请求对象
:return: 注册界面
"""
return render(request, 'register.html')
图形验证码
1.准备captcha包(该包用于生成图形验证码)
2.安装Python处理图片的库
pip install Pillow
3.图形验证码实现
from django.http import HttpResponseBadRequest,HttpResponse
from libs.captcha.captcha import captcha
from django_redis import get_redis_connection
class ImageCodeView(View):
def get(self,request):
#获取前端传递过来的参数
uuid=request.GET.get('uuid')
#判断参数是否为None
if uuid is None:
return HttpResponseBadRequest('请求参数错误')
# 获取验证码内容和验证码图片二进制数据
text, image = captcha.generate_captcha()
# 将图片验内容保存到redis中,并设置过期时间
redis_conn = get_redis_connection('default')
redis_conn.setex('img:%s' % uuid, 300, text)
# 返回响应,将生成的图片以content_type为image/jpeg的形式返回给请求
return HttpResponse(image, content_type='image/jpeg')
4.配置路由
from django.urls import path
from users.views import ImageCodeView
urlpatterns = [
# 参数1:路由
# 参数2:视图函数
# 参数3:路由名,方便通过reverse来获取路由
path('imagecode/', ImageCodeView.as_view(),name='imagecode'),
]
定义用户注册路由
1.在主工程的urls.py配置子应用的访问路由。
from django.contrib import admin
from django.urls import path,include
urlpatterns = [
path('admin/', admin.site.urls),
# include 参数1要设置为元组(urlconf_module, app_name)
# namespace 设置命名空间
path('', include(('users.urls', 'users'), namespace='users')),
]
2.在子应用中创建urls.py文件,在其添加自己的访问路由信息
from django.urls import path
from users.views import RegisterView
urlpatterns = [
# 参数1:路由
# 参数2:视图函数
# 参数3:路由名,方便通过reverse来获取路由
path('register/',RegisterView.as_view(),name='register'),
]
创建首页子应用
注册成功,重定向到首页
python manage.py startapp home
定义首页视图
from django.views import View
class IndexView(View):
"""首页广告"""
def get(self, request):
"""提供首页广告界面"""
return render(request, 'index.html')
配置首页路由
在home子应用中创建urls.py文件,并定义子路由
from django.urls import path
from home.views import IndexView
urlpatterns = [
path('', IndexView.as_view(),name='index'),
]
在主工程的urls.py总路由中添加子应用路由引导
from django.urls import path, include
urlpatterns = [
path('', include(('home.urls','home'),namespace='home')),
]
二、登录
用户名登录
1.在users.views.py文件中定义视图
from django.contrib.auth import login
from django.contrib.auth import authenticate
class LoginView(View):
def get(self, request):
return render(request, 'login.html')
def post(self, request):
# 接受参数
mobile = request.POST.get('mobile')
password = request.POST.get('password')
remember = request.POST.get('remember')
# 校验参数
# 判断参数是否齐全
if not all([mobile, password]):
return HttpResponseBadRequest('缺少必传参数')
# 判断手机号是否正确
if not re.match(r'^1[3-9]\d{9}$', mobile):
return HttpResponseBadRequest('请输入正确的手机号')
# 判断密码是否是8-20个数字
if not re.match(r'^[0-9A-Za-z]{8,20}$', password):
return HttpResponseBadRequest('密码最少8位,最长20位')
# 认证登录用户
"""
默认的认证方法中是对username进行认证。我们需要修改认证的字段为mobile。所以我们需要在User的模型中修改
USERNAME_FIELD='mobile'才能实现手机号的认证
"""
user = authenticate(mobile=mobile, password=password)
if user is None:
return HttpResponseBadRequest('用户名或密码错误')
# 实现状态保持
# Django用户认证系统提供了login()方法 封装了写入session的操作,帮助我们快速实现状态保持
login(request, user)
# 响应登录结果
next = request.GET.get('next')
if next:
response = redirect(next)
else:
# 重定向到首页 未登录
response = redirect(reverse('home:index'))
# 设置状态保持的周期
if remember != 'on':
# 没有记住用户:浏览器会话结束就过期
request.session.set_expiry(0)
# 设置cookie
response.set_cookie('is_login', True)
response.set_cookie('username', user.username, max_age=30 * 24 * 3600)
else:
# 记住用户:None表示两周后过期
request.session.set_expiry(None)
# 设置cookie
response.set_cookie('is_login', True, max_age=14 * 24 * 3600)
response.set_cookie('username', user.username, max_age=30 * 24 * 3600)
# 返回响应
return response
2.在users.urls.py文件中定义路由
from users.views import LoginView
urlpatterns = [
# 参数1:路由
# 参数2:视图函数
# 参数3:路由名,方便通过reverse来获取路由
path('login/', LoginView.as_view(),name='login'),
]
注意:
默认的认证方法中是对username进行认证。我们需要修改认证的字段为mobile。所以我们需要在User的模型中修改。
USERNAME_FIELD=’mobile’才能实现手机号的认证
登录状态
1. login()方法介绍
- 状态保持:
- 将通过认证的用户的唯一标识信息(比如:用户ID)写入到当前session会话中
- login()方法:
- Django用户认证系统提供了login()方法
- 封装了写入session的操作,帮助我们快速实现状态保持
- login()位置:
实现状态保持
login(request, user)
响应注册结果
跳转到首页
response = redirect(reverse(‘home:index’))
设置cookie
登录状态,会话结束后自动过期
response.set_cookie(‘is_login’,True)
设置用户名有效期一个月
response.set_cookie(‘username’,user.username,max_age=30243600)
return response
<a name="Y110F"></a>
## 退出
<a name="k77qT"></a>
### logout()方法介绍
1. 退出登录:
- 回顾登录:将通过认证的用户的唯一标识信息,写入到当前session会话中
- 退出登录:正好和登录相反(清理session会话信息)
2. logout()方法:
- Django用户认证系统提供了logout()方法
- 封装了清理session的操作,帮助我们快速实现登出一个用户
3. logout()位置:
- django.contrib.auth.__init__.py文件中
logout(request)
```python
# 退出
class LogoutView(View):
def get(self, request):
# 清理session
logout(request)
# 退出登录,重定向到登录页
response = redirect(reverse('home:index'))
# 退出登录时清除cookie中的登录状态
response.delete_cookie('is_login')
return response
三、忘记密码
1.在users.views.py文件中定义视图
# 忘记密码
class ForgetPasswordView(View):
def get(self, request):
return render(request, 'forget_password.html')
def post(self, request):
# 接收参数
mobile = request.POST.get('mobile')
password = request.POST.get('password')
password2 = request.POST.get('password2')
smscode = request.POST.get('sms_code')
# 判断参数是否齐全
if not all([mobile, password, password2, smscode]):
return HttpResponseBadRequest('缺少必传参数')
# 判断手机号是否合法
if not re.match(r'^1[3-9]\d{9}$', mobile):
return HttpResponseBadRequest('请输入正确的手机号码')
# 判断密码是否是8-20个数字
if not re.match(r'^[0-9A-Za-z]{8,20}$', password):
return HttpResponseBadRequest('请输入8-20位的密码')
# 判断两次密码是否一致
if password != password2:
return HttpResponseBadRequest('两次输入的密码不一致')
# 验证短信验证码
redis_conn = get_redis_connection('default')
sms_code_server = redis_conn.get('sms:%s' % mobile)
if sms_code_server is None:
return HttpResponseBadRequest('短信验证码已过期')
if smscode != sms_code_server.decode():
return HttpResponseBadRequest('短信验证码错误')
# 根据手机号查询数据
try:
user = User.objects.get(mobile=mobile)
except User.DoesNotExist:
# 如果该手机号不存在,则注册个新用户
try:
User.objects.create_user(username=mobile, mobile=mobile, password=password)
except Exception:
return HttpResponseBadRequest('修改失败,请稍后再试')
else:
# 修改用户密码
user.set_password(password)
user.save()
# 跳转到登录页面
response = redirect(reverse('users:login'))
return response
2.在users.urls.py文件中定义路由
from users.views import ForgetPasswordView
urlpatterns = [
# 参数1:路由
# 参数2:视图函数
# 参数3:路由名,方便通过reverse来获取路由
path('forgetpassword/', ForgetPasswordView.as_view(),name='forgetpassword'),
]
四、用户中心
个人中心展示
1.在users.views.py文件中定义视图
"""
Django用户认证系统提供了方法
request.user.is_authenticated()来判断用户是否登录。如果通过登录验证则返回True。反之,返回False。
LoginRequiredMixin封装了判断用户是否登录的操作。
"""
# 用户中心展示
class UserCenterView(LoginRequiredMixin, View):
#查询
def get(self, request):
# 获取用户信息
user = request.user
# 组织模板渲染数据
context = {
'username': user.username,
'mobile': user.mobile,
'avatar': user.avatar.url if user.avatar else None,
'user_desc': user.user_desc
}
return render(request, 'center.html', context=context)
#修改
def post(self, request):
# 接收数据
user = request.user
avatar = request.FILES.get('avatar')
username = request.POST.get('username', user.username)
user_desc = request.POST.get('desc', user.user_desc)
# 修改数据库数据
try:
user.username = username
user.user_desc = user_desc
if avatar:
user.avatar = avatar
user.save()
except Exception as e:
logger.error(e)
return HttpResponseBadRequest('更新失败,请稍后再试')
# 返回响应,刷新页面
response = redirect(reverse('users:center'))
##更新cookie信息
response.set_cookie('username', user.username, max_age=30 * 24 * 3600)
return response
2.在users.urls.py文件中定义路由
from users.views import UserCenterView
urlpatterns = [
# 参数1:路由
# 参数2:视图函数
# 参数3:路由名,方便通过reverse来获取路由
path('center/', UserCenterView.as_view(),name='center'),
]
注意:判断用户是否登录
Django用户认证系统提供了方法
- request.user.is_authenticated()来判断用户是否登录。如果通过登录验证则返回True。反之,返回False。
- LoginRequiredMixin封装了判断用户是否登录的操作。
1.用户中心使用LoginRequiredMixin
from django.views import View
from django.contrib.auth.mixins import LoginRequiredMixin
class UserCenterView(LoginRequiredMixin,View):
def get(self,request):
return render(request,'center.html')
2.设置未登录用户跳转的路由
#在工程的settings.py文件中,添加以下配置。
LOGIN_URL = '/login/'
3.根据登录的next参数设置登录跳转路由
# 实现状态保持
login(request, user)
# 响应登录结果
next = request.GET.get('next')
if next:
response= redirect(next)
else:
response = redirect(reverse('home:index'))
个人中心修改
用户中心头像的上传和展示
1.在settings.py文件中设置图片上传的路径并新建文件夹media
MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')
2.重新上传之后发现无法访问
解决方案:
第一步:设置图片的统一url都以media开头。在settings.py文件中设置
# 图片的统一路由
MEDIA_URL = '/media/'
第二步:设置路由匹配规则。在主工程的urls.py文件中设置
from django.contrib import admin
from django.urls import path,include
urlpatterns = [
path('admin/', admin.site.urls),
# include 参数1要设置为元组(urlconf_module, app_name)
# namespace 设置命名空间
path('', include(('users.urls', 'users'), namespace='users')),
path('', include(('home.urls','home'),namespace='home')),
]
#以下代码为设置图片访问路由规则
from django.conf import settings
from django.conf.urls.static import static
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
五、后台管理
网站的管理员负责查看、添加、修改、删除数据
- Django能够根据定义的模型类自动地生成管理模块
- 登陆站点:http://127.0.0.1:8000/admin

使用Django的管理模块, 需要按照如下步骤操作 :
本地化是将显示的语言、时间等使用本地的习惯,这里的本地化就是进行中国化.
- 中国大陆地区使用简体中文, 时区使用亚洲/上海时区, 注意这里不使用北京时区. ```python LANGUAGE_CODE = ‘zh-Hans’ #原配置信息为’en-us’
TIME_ZONE = ‘Asia/Shanghai’#原配置信息为’UTC’
<a name="WxTRS"></a>
## 2.创建管理员
**1.我们需要在自定义User模型中设置 REQUIRED_FIELDS**
```python
#创建超级管理员的需要必须输入的字段
REQUIRED_FIELDS = ['username','email']
2.在终端创建超级管理员
创建管理员的命令 :
python manage.py createsuperuser
- 重置密码
3.将各个模型注册到后台管理python manager.py changepassword 用户名
在应用的admin.py文件中注册模型类
