本文主要来自于mooc公开课Django课程
首先创建一个Django的虚拟环境:
pip install virtualenv
,然后使用virtualenv 虚拟环境名
建立一个虚拟环境,在windows下面的激活方法是
1 | cd django_virtual |
在linux下只需要将最后一步换位source activate
建立Django项目
在PyCharm建立程序时,直接选择Django程序,选择解释器为virtualenv建立的django环境,即可建立django项目
项目建立之后,我们得到了如下的目录结构,紫色的被标记为了templet目录,这样就能智能提示,如果你想要在import的时候不需要加入绝对路径,那么就可以mark as source root
接下来我们先尝试运行该项目,点击run,运行这个Django项目,可以看到运行在了本机的8000端口,点击该地址即可访问:
如果要配置监听所有ip,那么我们需要通过run-Edit configurations
,将监听端口改为0.0.0.0
Navicat使用
安装好Navicat之后,打开软件,建立连接,之后建立表,设计表的字段,设计完之后按ctrl+s
保存,之后就可以插入数据条目,这就是简单的使用方法,具体使用会在之后用到的时候详细介绍。下载地址请点击
Django目录结构
首先看看之前提到的建立django之后的目录结构,windows使用tree \F .
得到如下结构,linux中使用apt-get install tree
,然后tree .即可得到
:
1 | ├mooc_web |
- templetes文件夹主要放html文件
- 主文件夹下面有settings.py,以及manage.py
- 我们需要建立static文件夹,用于存放css和js文件,以及主要的图片文件
- 建立log文件夹,用于存放日志
- 建立media文件夹,用于存放用户上传的文件
- 建立apps文件夹,用于存放各个app
建立app
通过pycharm当中的tools-run manage.py task
,此时可以在shell中执行Django命令:
1 | startapp message |
此时就有了一个名为message的文件夹,将其拖入apps文件夹,自动生成了一个__init__.py
文件,这样就让apps变成一个可以导入的包,为了方便导入,那么我们需要将apps文件夹remark成source root,这样每次引用的时候就不需要import apps.message.view 而是可以直接 import message.view
这样在pycharm中引用变得方便了,但是在使用命令行运行的时候就会出错,此时我们需要在settings.py中将apps加入到根搜索路径(BASE_DIR)中
1 | ├── apps |
建立log文件夹用于存放日志,media用于存放用户的上传文件,建立static存放静态css和js文件
当app比较多的时候,就建立一个apps文件夹,将新建立的app拖进去
使用模板
将html模板放入template文件夹,在static文件夹中建立css文件夹,并放入style.css文件
settings配置
更改数据库配置
因为Django默认用的是sqlite数据库,我们要改成mysql数据库,打开项目的settings.py,找到DATABASES,将其中的:
- ENGINE改为
django.db.backends.mysql
- NAME改为Navicat中看到的
testDjango
- USER改为数据库的user名,我这里是root
- PASSWORD改为数据库的password,我这里也是root
- HOST改为localhost,也就是127.0.0.1
1 | DATABASES = { |
####migration生成数据表 通过tools-Run manage.py Task
来连接数据库,首先需要安装mysqlclient,用pip install mysqlclient
安装:
1 | > makemigrations # 用于生成一个基于你对模型改变的迁移,在这里就是数据库类型从sqlite迁移到mysql |
此时Django自动生成了一大堆数据库表,在Navicat中可以看到表的名称:
此时可以点击run运行整个系统,可以在127.0.0.1:8000上访问该网址
配置static文件夹地址
但是此时的style.css无法被找到,我们要在settings.py中配置一下static文件夹的地址,因为STATICFILES_DIRS
可能不止一个,所以用list的形式进行赋值,其中BASE_DIR是项目文件的根目录:
1 | STATICFILES_DIRS = [ |
urls.py配置和views.py函数
在urls.py中添加新的页面,页面的处理函数要在apps-message-views.py
中新增,首先我们在view.py
中构造如下函数,直接return render的模板,其中request参数是Django的请求,每个views函数都得有:
1 | def getform(request): |
项目配置流程
整体来说,先设置数据库和STATICFILES_DIRS,之后这一块不再动,主要就是views.py写后端逻辑,urls.py写页面地址url配置
Django orm 模型设计
普通的数据库调用方法,连接(connect),生成cursor,excute sql语句,cursor.fetchall( )
orm就是把一个表映射成一个类,比如要找出name只需要调用book.name
下面我们开始使用orm进行设计数据库:
找到message下面的models.py文件,在其中定义一个UserMessage类,用于存放我们需要的数据,所有model都要继承models.Model类:
1 | class UserMessage(models.Model): |
其中每一个字段都定义一个类型,常用的有CharField,EmailField,DateTimeField, IntergerField, ForeignKey, IPAddressField, FileField, ImageField
其中max_length表示最大长度,verbose_name表示别名.
自己定义的model还有一个内部类Meta,用于存放所有不是Field的字段,比如排序的顺序,数据表的名称等等
应用模型的改变
点击Tools-Run manage.py
,执行命令,发现找不到message这个model,所有我们要去settings.py中INSTALLED_APPS
加入’app.message’
再次执行
1 | > makemigrations message |
对数据表进行增删改查
查找数据
先引入model对象,from apps.message.models import UserMessage
,,利用model对象的objects方法,对数据进行操作
1 | all_message = UserMessage.objects.all() #这个是可以循环的 |
这里的all就是取出所有值,filter就是取出特定条件的值
增加数据
定义一个新的对象,并对其各个field赋值
1 | user_message = UserMessage() |
这样每次访问form页面的时候都可以存入一条记录
在html文件中需要进行如下更改:
1 | <form action="/form/" method="post" class="smart-green"> |
需要加入CSRF安全机制,
还可以通过页面的表单提交增加新的数据,request的POST属性中,以字典的形式存储了表单中提交的值,可以用python的get方法获取这些值,get的第二个参数为获取不到时候的默认值:
1 | if request.method == 'POST': |
删除数据
直接先查找到对象,然后用delete方法就可以删除对象
1 | all_message = UserMessage.objects.fileter(name='bob') |
显示数据库中的数据到页面
在view.py中,我们可以先取出数据,然后在render的时候,把需要传入的参数以一个dict的形式,传递给context,这样我们就可以在html文件中进行调用
1 | def getform(request): |
在HTML文件中调用参数的方法是两个大括号,input就输入在value里面,textarea就输入在两个标签之间:
1 | <input id="email" type="email" value={ { message.email } } name="email" placeholder="请输入邮箱地址"/> |
在HTML文件中使用python逻辑
在HTML文件中,使用python逻辑的方法是大括号加百分号,{ % python expression % }
if和end if成对出现
1 | <input id="name" type="text" value="{ % if not message.name == 'boobytest' % } |
比如在HTML中使用if和else的方法如上,当然if a==b 也可以使用 ifequal a b代替,取前五位也可以使用message.name|split:'5'
1 | { % ifequal a b% } { % endif % }#用于表示等于 |
Django提供了很多内置的方法,具体可以查看Django template built-in tags
使用别名关联url和HTML
url在配置过程中可能会改变,因此我们需要为url设置一个不变的名字供HTML调用
在url.py中:
1 | url(r'^form/$', getform,name='form') |
在comment.html中:
1 | <form action="{ % url 'form' % }" method="post" class="smart-green"> |
注意,在url配置中一定要加上/$
表示以/
结尾,不然再进行正则匹配的时候可能会匹配到别的网页
url匹配
必须在url前面加上^
,后面加上/$
,这样不会匹配出错
mooc开发实战
app设计
新建虚拟环境
1 | mkvirtualenv mooc |
新建Django项目
通过pycharm建立Django项目,名字为MxOnline,首先在settings.py中更改数据库引擎
1 | DATABASES = { |
通过Tools-run manage.py task
来生成数据库的表
1 | makemigrations |
扩展user表
首先startapp users
,在models当中,新建一个UserProfile
,继承django.contrib.auth.models.AbstractUser
,加入你需要的自定义字段,并定义好meta信息中的verbose_name
1 | from django.db import models |
然后run manage.py,通过makemigrations users
和migragate users
生成新的user表,可能会报错,报错时只需要将之前生成的所有表删除后重新生成即可
循环引用
避免交叉引用,不然会出错,使用上层app引用下层app
加入邮件验证码和轮播图
1 | class EmailVerifyRecord(models.Model): |
课程model设计
1 | Course -- 课程基本信息 |
一共有上述四张表
1 | from django.db import models |
添加organization的model
1 | CourseOrg -- 课程机构基本信息 |
添加如下
1 | from django.db import models |
添加operation的model
1 | UserAsk -- 用户咨询 |
添加如下:
1 | from django.db import models |
将所有app放到同一个文件夹下面
建立new python package, 把所有的app放到apps这个包下面,注意选择不改相对引用,并mark apps为source root
将apps这个文件夹加入到settings当中
1 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) |
建立后台管理系统
直接在run manage.py task中输入createsuperuser
,输入用户名,邮箱和密码就可以登录
更改语言和时区:
1 | LANGUAGE_CODE = 'zh-hans' #将语言改为中文 |
因为我们更改了admin的auth.user的model,因此需要注册user的model,在users
库中的admin.py文件中注册:
1 | from users.models import UserProfile |
登录http://127.0.0.1:8000/admin
就可以对用户进行修改
- pycharm全局搜索的快捷键是
ctrl+shift+f
使用xadmin
使用xadmin,因为我安装的Django 2.0.1版本,所以需要安装专门的xadmin for Django2.0
1 | pip install git+git://github.com/sshwsfc/xadmin.git@django2 |
在url.py中引入xadmin
1 | import xadmin |
在settings.py中注册xadmin和crispy_forms:
1 | INSTALLED_APPS = [ |
接下来同步xadmin的表:
1 | > makemigrations |
再打开http://127.0.0.1:8000/xadmin就可以访问xadmin的后台管理了
在管理用户信息的时候,会出现错误,这是由于我们用的Django是2.0.1版本,而教程中用到的是1.0+,根据pycharm报错的最后一条,打开widget.py文件,在74行修改如下
1 | input_html = [ht for ht in super(AdminSplitDateTime, self).render(name, value, attrs).split('/><') if ht != ''] |
通过源码安装xadmin
在mxonline下建立一个python package文件夹extra_apps,下载xadmin并解压,拷贝其中的xadmin文件夹到其中,并把extra_apps mark as source root,这样引入xadmin的时候就会从相对文件引入
同时在settings.py中把xadmin文件夹加入根搜索路径
注册邮箱验证码model
注册方法类似于admin的注册方式,只不过不是在admin.py中注册,而是要新建adminx.py,并且admin继承的是object
1 | import xadmin |
修改显示的邮件验证码存储记录的str名称:
1 | class EmailVerifyRecord(models.Model): |
- 注意:所有注册的Model名字都应该为
class Model名+Admin
添加搜索和显示列
在其中加入list_display(显示列), search_fields(搜索域), list_filter(过滤器)
1 | class LessonAdmin(object): |
如果要使用外键进行搜索,可以用两个下划线表示
1 | class LessonAdmin(object): |
xadmin全局配置
将全站的配置放在user app的admix.py中,新建一个class BaseSetting,用于配置主题
1 | from xadmin import views |
建立一个class GlobalSettings配置标题名称和footer名称
1 | class GlobalSettings: |
更改model名称
在每个model文件夹中的apps.py文件中加入verbose_name
1 | from django.apps import AppConfig |
然后在__init__.py
中加入default_app_config
1 | default_app_config = 'courses.apps.CoursesConfig' |
完成用户的登录功能
首先将前端给的Index.html(首页)文件和login.html(登录页)文件放入templates文件夹中
在根目录下建立static文件夹,存放css,images,js,media文件,并在settings.py中声明STATICFILES_DIRS=[os.path.join(BASE_DIR,'static')]
,注意:这里的STATICFILES_DIRS必须设置为list或者tuple形式,否则会报错
此时,将html文件中的所有css,js的文件路径修改为/static/css
和/static/js
接下来配置url,在url.py中引入TemplateView
1 | from django.views.generic import TemplateView |
这样就完成了页面配置,重启项目后就可以访问首页和登录页面
实现使用用户名或者邮箱都可以登录
现在users模块中新建CustomBackend类,继承ModelBackend,重写其中的authenticate函数,用Q函数实现或操作
1 | from django.contrib.auth.backends import ModelBackend |
写自己的login函数login,并将其写到urls.py中
1 | def my_login(request): |
1 | url(r'^login/', my_login, name='login') |
在settings.py中加入AUTHENTICATION_BACKENDS=('users.views.CustomBackend',)
,将认证后台改为自己写的后台
在点击登陆后,我们需要跳转回首页或者是报告密码错误,此时request被传递到网页中,可以在跳转后显示自己的用户名
1 | <dd>{ { request.POST.username } }<img class="down fr" src="/static/images/top_down.png"/></dd> |
将用户登录改成类的方法
views.py中加入自己的类:
1 | from django.views.generic import View |
在urls.py中将loginview注册:
1 | url(r'^login/', LoginView.as_view(), name='login') |
实现用户名和密码的长度和空检验
在users模块汇总建立forms.py用于检验表单
1 | from django import forms |
在views.py中加入loginform的验证,逻辑是如果有效,则提取表单中的username和password,验证成功后,用login函数登录,返回index页面;如果验证失败,返回登录页显示用户或密码错误;如果检测到form有错误,返回登录页,显示错误类型
1 | class LoginView(View): |
在login.html中显示错误类型:
1 | <div class="error btns login-form-tips" id="jsLoginTips">{ % for key, error in login_form.errors.items % } |
使用cookies进行登录
http本身是一种无状态协议,每次发送请求,服务器返回请求的数据,如果要记住登录状态就需要cookies django的cookie由session_key和session_data以及expire_data组成,实现是通过setings.py中的’django.contrib.sessions’, 每个域名之下的cookies是不能互相访问的
实现user的注册功能
先拷贝register.html到template中,配置url,
1 | url(r'^register/',RegisterView.as_view,name='register'), |
然后在views.py
中加入RegisterView类
1 | class RegisterView(View): |
在HTML代码中修改指向
1 | <a style="color:white" class="fr registerbtn" href="{ % url 'register' % }">注册</a> |
修改其css和js文件的地址,这里介绍第二种修改的方法 首先在html文件中输入{ %load staticfiles% }
然后在需要修改地址的地方输入{ %static '/css/reset.css'% }
加入验证码功能
- 先安装django-simple-captcha模块
1 | pip install django-simple-captcha |
- 根据官方文档的提示添加captcha到settings.py当中的INSTALLED_APPS
- 运行makemigrations,migrate
- 添加实例到urls.py中
1 | urlpatterns += [ |
然后在forms.py中加入一个新的register_form,在其中加入captchafiled
1 | from django import forms |
在view.py
中加入registerview
1 | class RegisterView(View): |
修改register.html
1 | <div class="tab-form"> |
处理用户激活
在urls.py中插入需要激活的页面,用(?P<active_code>.*?)/$
,?P
是表示parameter的意思,active_code表示你需要提取的变量,后面的.*?
表示正则表达式
1 | url(r'^active/(?P<active_code>.*?)/$',ActiveUserView.as_view()), |
在view中加入新的ActiveUserView,在get中可以拿到刚才在urls.py中定义的active_code参数,先判断这个值在我的数据库中是否存在
1 | class ActiveUserView(View): |
在LoginView中加入是否激活的判断
1 | def post(self, request): |
处理忘记密码
在urls.py中加入新的页面
1 | url(r'^reset/(?P<reset_code>.*?)/$', ResetView.as_view(), name='reset_pwd'), |
在views.py中加入新的view
1 | class ResetView(View): |
在forms.py中加入ResetPwdForm
1 | class ResetPwdForm(forms.Form): |
在template中加入password_reset.html
1 | <!--修改action为modifypwd--> |