本文档为 "使用 Python3.6 + Django2.1 搭建个人博客" 系列文档的第一篇,主要讲述如何创建 Django 项目、配置 MySQL 数据库、自定义用户模型等。
创建虚拟环境
- 创建虚拟环境
[ allenlideMacBook-Pro:~ allen ]$ mkvirtualenv opcoder
- 进入虚拟环境并安装依赖包
(opcoder) allenlideMacBook-Pro:~ allen$ pip3 install django==2.1.10
- 查看当前虚拟环境下已安装的依赖包
(opcoder) allenlideMacBook-Pro:~ allen$ pip3 list Package Version ---------- ------- Django 2.1.10 pip 19.2.1 pytz 2019.2 setuptools 41.0.1 wheel 0.33.4
创建 MySQL 数据库
MySQL 数据库字符集选择 utf8mb4 可支持 emoji
创建 Django 项目
- 利用 Pycharm 工具创建 Django 项目
配置数据库连接
- 安装依赖包
(opcoder) allenlideMacBook-Pro:~ allen$ pip3 install pymysql
- 在
opcoder/setting.py
配置文件中,配置数据库信息
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'opcoder', 'USER': 'root', 'PASSWORD': 'password', 'HOST': '127.0.0.1', 'PORT': 3306, 'OPTIONS': {'charset': 'utf8mb4', } } }
- 在
opcoder/__init__.py
文件中,更改默认数据库连接
import pymysql pymysql.install_as_MySQLdb()
配置静态文件路径
- 在
opcoder/setting.py
配置文件中,配置静态文件路径
STATICFILES_DIRS = ( os.path.join(BASE_DIR, 'static'), )
更改时区
- 在
opcoder/setting.py
配置文件中,配置时区
LANGUAGE_CODE = 'zh-hans' TIME_ZONE = 'Asia/Shanghai' USE_I18N = True USE_L10N = True USE_TZ = False # 关闭国际时间,不然数据库报错
自定义用户模型
- 安装 图片/文件 处理依赖包
(opcoder) allenlideMacBook-Pro:~ allen$ pip3 install Pillow (opcoder) allenlideMacBook-Pro:~ allen$ pip3 install django-imagekit
创建 users 应用
(opcoder) allenlideMacBook-Pro:blog allen$ python3 manage.py startapp users
- 在
opcoder/setting.py
配置文件中,添加 app
INSTALLED_APPS = [ ..., 'imagekit', 'users', ]
- 在
users/models.py
文件中,创建 UserProfile 数据模型
from django.db import models from django.contrib.auth.models import AbstractUser from imagekit.models import ProcessedImageField from imagekit.processors import ResizeToFill from datetime import datetime class UserProfile(AbstractUser): link = models.URLField('个人网址', blank=True, help_text='提示:网址必须填写以 http 开头的完整形式') nick_name = models.CharField(max_length=20, verbose_name='昵称', null=True, blank=True) mobile = models.CharField(max_length=11, verbose_name='手机', null=True, blank=True) address = models.CharField(max_length=200, verbose_name='地址', null=True, blank=True) avatar = ProcessedImageField( upload_to='avatar/%Y/%m/%d', default='avatar/default.png', verbose_name='头像', processors=[ResizeToFill(80, 80)] ) class Meta: verbose_name = '用户信息' verbose_name_plural = verbose_name ordering = ['-id'] def __str__(self): return self.username
- 在
opcoder/settings.py
文件中为 AUTH_USER_MODEL 设置一个值来重写默认的用户表
INSTALLED_APPS = [ ..., 'users', 'imagekit', ] AUTH_USER_MODEL = 'users.UserProfile'
配置图片/文件上传
因为数据模型中使用了 ImageField 类型, 所以我们要为文件/图片配置上传目录
- 在项目根目录下创建 media 目录树并维护默认图片
- 在
opcoder/settings.py
文件中配置 文件/图片 上传路径
# 用户 文件/图片 上传配置 MEDIA_URL = '/media/' MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
- 在
opcoder/settings.py
文件中配置添加以下信息
TEMPLATES = [ { ..., 'OPTIONS': { 'context_processors': [ ..., 'django.template.context_processors.media', ], }, }, ]
- 在
opcoder/urls.py
文件中配置处理上传文件访问的 URL
from django.contrib import admin from django.conf.urls import url from django.views.static import serve from opcoder.settings import MEDIA_ROOT urlpatterns = [ url(r'admin/', admin.site.urls), url(r'^media/(?P<path>.*)$', serve, {"document_root": MEDIA_ROOT}), ]
生成数据库
- 执行数据库生成语句
(opcoder) allenlideMacBook-Pro:blog allen$ python3 manage.py makemigrations (opcoder) allenlideMacBook-Pro:blog allen$ python3 manage.py migrate
- 查看生成的表结构
创建超级用户
- 创建超级用户
(opcoder) allenlideMacBook-Pro:blog allen$ python3 manage.py createsuperuser 用户名: admin 电子邮件地址: Password: Password (again): Superuser created successfully.
- 使用超级用户登录后台管理页面
(opcoder) allenlideMacBook-Pro:blog allen$ python manage.py runserver
注册 admin
为了让 admin 界面管理某个数据模型,我们需要先注册该数据模型到 admin。
普通注册
- 查看原始页面
- 在
users/admin.py
文件中添加如下信息
from django.contrib import admin from .models import UserProfile class UserProfileAdmin(admin.ModelAdmin): list_display = ('username', 'email', 'is_staff', 'is_active', 'date_joined') list_filter = ('is_staff', 'is_superuser', 'is_active', 'groups') admin.site.register(UserProfile, UserProfileAdmin)
- 查看注册数据模型后的页面
装饰器注册
- 在
users/admin.py
文件中添加如下信息
from django.contrib import admin from .models import UserProfile @admin.register(UserProfile) class UserProfileAdmin(admin.ModelAdmin): # 显示字段 list_display = ('username', 'email', 'is_staff', 'is_active', 'date_joined') # 过滤字段 list_filter = ('is_staff', 'is_superuser', 'is_active', 'groups') fieldsets = ( ('基础信息', {'fields': (('username', 'password'), ('email', 'mobile'),)}), ('权限信息', {'fields': (('is_active', 'is_staff', 'is_superuser'), 'groups', 'user_permissions')}), ('重要日期', {'fields': (('last_login', 'date_joined'),)}), ) # 搜索字段 search_fields = ('username', 'email')
Django 后台管理
Django 自带的后台管理是 Django 明显的特色之一,可以让我们快速便捷的管理数据,后台管理可以在各个 app 的 admin.py 文件中进行控制。
修改登录界面名称
- 先找到 admin 的页面文件
(opcoder) allenlideMacBook-Pro:admin allen$ pwd /Users/allen/.VirtualEnvs/opcoder/lib/python3.6/site-packages/django/contrib/admin/templates/admin
- 初始登录界面
- 找到
base_site.html
来修改名称
- 修改名称
- 重启服务并检查修改是否成功
修改应用名称
- 在
users/apps.py
文件中添加如下信息
from django.apps import AppConfig class UsersConfig(AppConfig): name = 'users' verbose_name = "用户信息"
- 在
users/__init__.py
文件中添加如下信息
default_app_config = 'users.apps.UsersConfig'
- 查看应用的显示名称,已经由
USERS
改为了用户信息
明文密码转密文
使用自定义用户模型后,在 Django 后台会使用明文密码,通过定制认证功能,可以实现密码的密文存储。
- 在后台页面新增一个用户,我们可以看到其密码是明文存储的
- 将
users/admin.py
修改为如下内容
from django.contrib import admin from django import forms from django.contrib.auth.admin import UserAdmin as BaseUserAdmin from django.contrib.auth.forms import ReadOnlyPasswordHashField from .models import UserProfile class UserCreationForm(forms.ModelForm): password1 = forms.CharField(label='密码', widget=forms.PasswordInput) password2 = forms.CharField(label='密码确认', widget=forms.PasswordInput) class Meta: model = UserProfile fields = ('username', 'email', ) def clean_password2(self): password1 = self.cleaned_data.get("password1") password2 = self.cleaned_data.get("password2") if password1 and password2 and password1 != password2: raise forms.ValidationError("Passwords don't match") return password2 def save(self, commit=True): user = super().save(commit=False) user.set_password(self.cleaned_data["password1"]) if commit: user.save() return user class UserChangeForm(forms.ModelForm): password = ReadOnlyPasswordHashField() class Meta: model = UserProfile fields = ('username', 'email', 'password', 'is_active') def clean_password(self): return self.initial["password"] class UserAdmin(BaseUserAdmin): form = UserChangeForm add_form = UserCreationForm list_display = ('username', 'email', 'is_staff', 'is_active', 'date_joined') list_filter = ('is_staff', 'is_superuser', 'is_active', 'groups') fieldsets = ( ('基础信息', {'fields': (('username', 'password'), ('email', 'mobile'), )}), ('权限信息', {'fields': (('is_active', 'is_staff', 'is_superuser'), 'groups', 'user_permissions')}), ('重要日期', {'fields': (('last_login', 'date_joined'), )}), ) add_fieldsets = ( (None, { 'classes': ('wide',), 'fields': (('username', 'email'), ('password1', 'password2'), )} ), ) search_fields = ('username', 'email') ordering = ('username', 'email',) filter_horizontal = () class UserProfileAdmin(admin.ModelAdmin): list_display = ('username', 'email', 'is_staff', 'is_active', 'date_joined') list_filter = ('is_staff', 'is_superuser', 'is_active', 'groups') fieldsets = ( ('基础信息', {'fields': (('username', 'password'), ('email', 'mobile'), )}), ('权限信息', {'fields': (('is_active', 'is_staff', 'is_superuser'), 'groups', 'user_permissions')}), ('重要日期', {'fields': (('last_login', 'date_joined'), )}), ) search_fields = ('username', 'email') admin.site.register(UserProfile, UserAdmin)
美化后台管理页面
- 安装依赖包
(opcoder) allenlideMacBook-Pro:blog allen$ pip3 install bootstrap-admin
- 添加至
opcoder/settings.py
文件的 INSTALLED_APPS 中
INSTALLED_APPS = [ 'bootstrap_admin', # 这个必须放在所有app的前面 ..., ]
如果在安装 bootstrap-admin 后,后台页面显示有问题,可以使用 Ctrl+F5
强制刷新一下而在 MAC 下需使用 command+shift+r
强制刷新。
- 查看美化后的后台管理页面
原创文章,转载请注明出处:http://www.opcoder.cn/article/30/