第 1 章 课程介绍

1-1 项目演示和课程介绍;

第 2 章 Windows下搭建开发环境

2-1 Pycharm、Navicat和Python解释器的安装;

http://www.jetbrains.com/pycharm/

2-2 Virtualenv安装和配置;

2-3 Pycharm和Navicat的简单使用;

第 3 章 通过留言板功能回顾Django基础知识

3-1 Django目录介绍

  • djangoproject;
  • log;
  • media;
  • apps;
  • templates;
  • static;

3-2 配置表单页面

3.2.1 安装pip install pymysql并在项目根目录的__init__.py文件中添加如下配置,解决报错问题:(使用pymysql代替mysqlclient、MySQL-python)

PS:不同的Python版本,使用不同的pip,比如pip3 install xxxx; pip install xxx;

Error:MySQLdb Module 'Did you install mysqlclient or MySQL-python?

使用django开发时,发现安装了mysql和mysql-python还是报错,可以__init__.py文件中加入以下代码解决:

import pymysql

pymysql.install_as_MySQLdb()

3.2.2 使用Pycharm工具作为MySQL图形化工具连接MySQL数据库;

3.2.3 使用Pycharm工具启动并运行Django项目;

3.2.4 settings.py配置;

  • DATABASES = {}
  • TEMPLATES下的DIRS;
  • 新增STATICFILES_DIRS = []
  • INSTALLED_APPS = []

3.2.5 python manage.py makemigrations& python mange.py migrate 进行数据库迁移;

3.2.6 编写urls.py;

3.2.7 编写views.py;

3.2.8 通过render渲染html文件;

settings.py;

"""
Django settings for DjangoStart project. Generated by 'django-admin startproject' using Django 1.11.15. For more information on this file, see
https://docs.djangoproject.com/en/1.11/topics/settings/ For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.11/ref/settings/
""" import os # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'p2rjom3lf=n&y+piru&j-ky+$l_-9$o710k9=nrchp!2j=^gnk' # SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True ALLOWED_HOSTS = [] # Application definition INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
] MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
] ROOT_URLCONF = 'DjangoStart.urls' TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')]
,
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
] WSGI_APPLICATION = 'DjangoStart.wsgi.application' # Database
# https://docs.djangoproject.com/en/1.11/ref/settings/#databases # DATABASES = {
# 'default': {
# 'ENGINE': 'django.db.backends.sqlite3',
# 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
# }
# }
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'imc_django',
'USER': 'root',
'PASSWORD': 'Tqtl911!@#)^',
'HOST': '127.0.0.1',
'PORT': '',
} } # Password validation
# https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
] # Internationalization
# https://docs.djangoproject.com/en/1.11/topics/i18n/ LANGUAGE_CODE = 'en-us' TIME_ZONE = 'UTC' USE_I18N = True USE_L10N = True USE_TZ = True # Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.11/howto/static-files/ STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static')
]

message_form.html;

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<link rel="stylesheet" href="/static/css/style.css">
<link rel="stylesheet" href="/static/css/style.css">
</head>
<body>
<form action="/form/" method="post" class="smart-green">
<h1>留言信息
<span>请留下你的信息.</span>
</h1>
<label>
<span>姓名 :</span>
<input id="name" type="text" name="name" class="error" placeholder="请输入您的姓名"/>
<div class="error-msg"></div>
</label> <label>
<span>邮箱 :</span>
<input id="email" type="email" value="" name="email" placeholder="请输入邮箱地址"/>
<div class="error-msg"></div>
</label> <label>
<span>联系地址 :</span>
<input id="address" type="text" value="" name="address" placeholder="请输入联系地址"/>
<div class="error-msg"></div>
</label> <label>
<span>留言 :</span>
<textarea id="message" name="message" placeholder="请输入你的建议"></textarea>
<div class="error-msg"></div>
</label>
<div class="success-msg"></div>
<label>
<span>&nbsp;</span>
<input type="submit" class="button" value="提交"/>
</label>
</form> </body>
</html>

3-3 Django orm介绍与model设计

  3.3.1 Django-model初识;

  3.3.2 通过执行数据库迁移操作,生成以“应用名_表名”的数据表;

PS:补充

  • id如果不指定,自动创建;
  • verbose_name可以理解为表名的tag值;
  • class Meta指定表的相关属性,如表名、排序规则,即表级别操作!
Django中其他的字段类型:
models.ForeignKey
models.DateTimeField
models.IntegerField
models.IPAddressField
models.FileField
models.ImageField

models.py通过类的形式生成UserMessage表;

# -*- coding: utf-8 -*-
from __future__ import unicode_literals from django.db import models # Create your models here.
class UserMessage(models.Model):
object_id = models.CharField(max_length=50, default="", primary_key=True, verbose_name=u"主键")
name = models.CharField(max_length=32, null=True, blank=True, default="", verbose_name='用户名')
email = models.EmailField(verbose_name='邮箱')
address = models.CharField(max_length=100, verbose_name=u'联系地址')
message = models.CharField(max_length=500, verbose_name=u'留言信息')
"""
Django中其他的字段类型:
models.ForeignKey
models.DateTimeField
models.IntegerField
models.IPAddressField
models.FileField
models.ImageField
""" class Meta:
verbose_name = u'用户留言信息'
verbose_name_plural = verbose_name # db_table = "user_message"
# ordering = "-object_id"
# ordering = "object_id"

3-4 Django model的增删改查

  3.4.1 {% crsf_token %}防止跨站请求伪造,form表单必须配置 ;

  3.4.2 /form/,尾部加“/”的问题;

  3.4.3 Django中的debug模式应用;

  3.4.4 同级目录模块之间的导入问题;

  3.4.5 数据的创建和删除;

  3.4.6 Django-settings.py配置文件中,INSTALLED_APPS的配置问题;

# -*- coding: utf-8 -*-

from __future__ import unicode_literals
import os, django os.environ.setdefault("DJANGO_SETTINGS_MODULE", "DjangoStart.settings") # project_name 项目名称
django.setup() from django.shortcuts import render, redirect
from django.http import HttpResponse
from message.models import UserMessage # Create your views here.
def getform(request):
all_messages = UserMessage.objects.filter(name='cuixiaozhao', address='北京') # Django的QuerySet类型;
for message in all_messages:
# 数据的删除
message.delete()
# print message.name # # 数据的创建:
# if request.method == "POST":
# name = request.POST.get('name', '')
# message = request.POST.get('message', '')
# address = request.POST.get('address', '')
# email = request.POST.get('email', '')
# user_message = UserMessage()
# user_message.name = name
# user_message.message = message
# user_message.address = address
# user_message.email = email
# user_message.object_id = 'HelloDjango1'
# user_message.save() # Debug模式;
# user_message = UserMessage()
# user_message.name = 'cuixiaosi'
# user_message.message = 'HelloDjango'
# user_message.address = '上海'
# user_message.email = 'tqtl911@163.com'
# user_message.object_id = 'HelloDjango'
# user_message.save() return render(request, 'message_form.html', )

3-5 Django url templates 配置

3.5.1 Django中的url配置;

  • URL中的注意事项之url(r'^form/$', views.getform,name='go_form');

3.5.2 Django中的templates配置;

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<link rel="stylesheet" href="/static/css/style.css">
</head>
<body>
<form action="{% url 'go_form' %}" method="post" class="smart-green">
{% csrf_token %}
<h1>留言信息
<span>请留下你的信息.</span>
</h1>
<label>
<span>姓名 :</span>
{# <input id="name" type="text" value="{{ message.name }}" na me="name" class="error" placeholder="请输入您的姓名"/>#}
<input id="name" type="text" value="{% ifequal message.name|slice:'5' '崔晓昭' %}崔天晴{% else %} 天晴天朗 {% endifequal %}" name="name" class="error" placeholder="请输入您的姓名"/>
<div class="error-msg"></div>
</label> <label>
<span>邮箱 :</span>
<input id="email" type="email" value="{{ message.email }}" name="email" placeholder="请输入邮箱地址"/>
<div class="error-msg"></div>
</label> <label>
<span>联系地址 :</span>
<input id="address" type="text" value="{{ message.address }}" name="address" placeholder="请输入联系地址"/>
<div class="error-msg"></div>
</label> <label>
<span>留言 :</span>
<textarea id="message" name="message" placeholder="请输入你的建议">{{ message.message }}</textarea>
<div class="error-msg"></div>
</label>
<div class="success-msg"></div>
<label>
<span>&nbsp;</span>
<input type="submit" class="button" value="提交"/>
</label>
</form> </body>
</html>

第 4 章 需求分析和model设计

4-1 使用Python3.6 和 Django1.11 开发系统前注意事项(补充小节)

4.1.1 mkvirtualenv -p 指定Python3.x的安装路径;

4.1.2 def __str__(self):的使用;代替__unicode__(self:;

4.1.3 使用Python3开发,使用Mysqlclient代替MySQL-python,最终pymysql代替两者;

4.1.4 使用xadmin以及extra_apps;

4.1.5 github下的mxonline_resource;

4.1.6 requirement.txt安装依赖;

4.1.7 富文本工具DjangoUeditor的使用注意;

4-2 使用Django2.0开始课程的注意事项

4.2.1 慕课网Django+xadmin打造生鲜电商项目;

4.2.2 基于慕课网的 github地址申请;

http://apply.projectsedu.com/

4-3 Django-app设计

4.3.1 django-app的设计;

4.3.2 各个app models设计

4.3.3 数据表生成与修改;

4-4 新建项目

4.4.1 使用Pycharm新建Django项目-MxOnline;

4.4.2 使用NavicatForMySQL工具,创建数据库实例:MxOnline;

4.4.3 安装mysql驱动-pip install mysql-python报错的替代解决方案之pymysql;

4.4.4 settings.py中修改DATABASES配置;

4.4.5 python manage.py执行数据库迁移操作,并生成数据表;

DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'MxOnline',
'USER': 'root',
'PASSWORD': 'Tqtl911!@#)^',
'HOST': '127.0.0.1',
'PORT': '',
'OPTIONS': {
'autocommit': True,
},
}
}

4-5 自定义userprofile

4.5.1 auth_user表字段了解;

4.5.2 UserProfile类继承from django.contrib.auth.models import AbstractUser来拓展auth_user表字段;

4.5.3 settings.py中INSTALLED_APPS进行应用的注册;

4.5.4 AUTH_USER_MODEL = "users.UserProfile"在settings.py中的配置;

4.5.5 添加models.py后,必须执行数据库迁移操作:python manage.py makemigrations ;python manage.py migrate;

4.5.6 models.ImageField依赖pillow第三方库,pip3 install pillow

models.py;

# _*_ encoding:utf-8 _*_
from __future__ import unicode_literals from django.db import models
# 继承AbstractUser
from django.contrib.auth.models import AbstractUser # Create your models here. class UserProfile(AbstractUser):
nick_name = models.CharField(max_length=50, verbose_name=u'昵称', default="")
birthday = models.DateField(verbose_name=u'生日', null=True, blank=True)
gender = models.CharField(max_length=5,choices=(("male", u"男"), ("female", u"女")), default="female")
address = models.CharField(max_length=100, default=u"")
mobile = models.CharField(max_length=11, null=True, blank=True)
image = models.ImageField(upload_to="image/%Y/%m", default=u"image/default.png", max_length=100) class Meta:
verbose_name = "用户信息"
verbose_name_plural = verbose_name def __unicode__(self):
return self.username

Unhandled exception in thread started by <function wrapper at 0x10f403e60>
Traceback (most recent call last):
File "/Users/cuixiaozhao/PycharmProjects/imooc/MxOnline/venv/lib/python2.7/site-packages/django/utils/autoreload.py", line 226, in wrapper
fn(*args, **kwargs)
File "/Users/cuixiaozhao/PycharmProjects/imooc/MxOnline/venv/lib/python2.7/site-packages/django/core/management/commands/runserver.py", line 116, in inner_run
self.check(display_num_errors=True)
File "/Users/cuixiaozhao/PycharmProjects/imooc/MxOnline/venv/lib/python2.7/site-packages/django/core/management/base.py", line 472, in check
raise SystemCheckError(msg)
django.core.management.base.SystemCheckError: SystemCheckError: System check identified some issues: ERRORS:
users.UserProfile.gender: (fields.E120) CharFields must define a 'max_length' attribute.
users.UserProfile.image: (fields.E210) Cannot use ImageField because Pillow is not installed.
HINT: Get Pillow at https://pypi.python.org/pypi/Pillow or run command "pip install Pillow". System check identified 2 issues (0 silenced).

4-6 user models.py设计

4.6.1 循环引用;

4.6.2 定义EmailVerifyRecord类;

4.6.3 models.py中添加# _*_  coding:utf-8  _*_ ;

# _*_ encoding:utf-8 _*_
from __future__ import unicode_literals
from datetime import datetime from django.db import models
# 继承AbstractUser
from django.contrib.auth.models import AbstractUser # Create your models here. class UserProfile(AbstractUser):
nick_name = models.CharField(max_length=50, verbose_name=u'昵称', default="")
birthday = models.DateField(verbose_name=u'生日', null=True, blank=True)
gender = models.CharField(max_length=5, choices=(("male", u"男"), ("female", u"女")), default="female")
address = models.CharField(max_length=100, default=u"")
mobile = models.CharField(max_length=11, null=True, blank=True)
image = models.ImageField(upload_to="image/%Y/%m", default=u"image/default.png", max_length=100) class Meta:
verbose_name = u"用户信息"
verbose_name_plural = verbose_name def __unicode__(self):
return self.username class EmailVerifyRecord(models.Model):
code = models.CharField(max_length=20, verbose_name=u'验证码')
email = models.EmailField(max_length=50, verbose_name=u'邮箱')
send_type = models.CharField(choices=(("register", u"注册"), ("forget", u"找回密码")), max_length=10)
send_time = models.DateTimeField(default=datetime.now) # datetime.now()不添加括号 class Meta:
verbose_name = u"邮箱验证码"
verbose_name_plural = verbose_name class Banner(models.Model):
title = models.CharField(max_length=100, verbose_name=u"标题")
image = models.ImageField(upload_to="banner/%Y/%m", verbose_name=u"轮播图")
url = models.URLField(max_length=200, verbose_name=u"访问地址")
index = models.IntegerField(default=100, verbose_name=u"顺序")
add_time = models.DateTimeField(default=datetime.now, verbose_name=u"添加时间") class Meta:
verbose_name = u"轮播图"
verbose_name_plural = verbose_name

4-7 course models.py设计

4.7.1 创建course应用; 

course/models.py设计;

# _*_ encoding:utf-8 _*_
from __future__ import unicode_literals
from datetime import datetime from django.db import models # Create your models here. # 创建四张表(类); class Course(models.Model):
name = models.CharField(max_length=50, verbose_name=u"")
desc = models.CharField(max_length=300, verbose_name=u"课程描述")
detail = models.TextField(verbose_name=u"课程详情")
degree = models.CharField(choices=(('cj', '初级'), ('zj', '中级'), ('gj', '高级')), max_length=100)
learn_times = models.IntegerField(default=0, verbose_name=u"学习时长(分钟数)")
students = models.IntegerField(default=0, verbose_name=u"学习人数")
fav_nums = models.IntegerField(default=0, verbose_name=u"收藏人数")
image = models.ImageField(upload_to="courses/%Y/%m", verbose_name=u"封面")
click_nums = models.IntegerField(default=0, verbose_name=u"点击数")
add_time = models.DateTimeField(default=datetime.now, verbose_name=u"添加时间") class Meta:
verbose_name = u"课程"
verbose_name_plural = verbose_name class Lesson(models.Model):
course = models.ForeignKey(Course, verbose_name=u"课程")
name = models.CharField(max_length=100, verbose_name=u"章节名称")
add_time = models.DateTimeField(default=datetime.now, verbose_name=u"添加时间") class Meta:
verbose_name = u"章节"
verbose_name_plural = verbose_name class Video(models.Model):
lesson = models.ForeignKey(Lesson, u"章节")
name = models.CharField(max_length=100, verbose_name=u"视频名称")
add_time = models.DateTimeField(default=datetime.now, verbose_name=u"添加时间") class Meta:
verbose_name = u"视频"
verbose_name_plural = verbose_name class CourseResource(models.Model):
course = models.ForeignKey(Course, verbose_name=u"课程")
name = models.CharField(max_length=100, verbose_name=u"名称")
download = models.FileField(upload_to="course/resource/%Y/%m", verbose_name=u"资源文件", max_length=100)
add_time = models.DateTimeField(default=datetime.now, verbose_name=u"添加时间") class Meta:
verbose_name = u"课程资源"
verbose_name_plural = verbose_name

4-8 organization models.py设计

4.8.1 创建organization 应用;

4.8.1 编写organizaiton/models.py;

# _*_ encoding:utf-8 _*_
from __future__ import unicode_literals
from datetime import datetime
from django.db import models # Create your models here.
class CityDict(models.Model):
name = models.CharField(max_length=20, verbose_name=u"城市")
desc = models.CharField(max_length=200, verbose_name=u"描述")
add_time = models.CharField(default=datetime.now) class Meta:
verbose_name = u"城市"
verbose_name_plural = verbose_name class CourseOrg(models.Model):
name = models.CharField(max_length=50, verbose_name=u"机构名称")
desc = models.TextField(verbose_name=u"机构描述")
click_nums = models.IntegerField(default=0, verbose_name=u"点击数")
fav_nums = models.IntegerField(default=0, verbose_name=u"收藏数")
image = models.ImageField(upload_to="org/%Y/%m", verbose_name=u"封面图片")
address = models.CharField(max_length=150, verbose_name=u"机构地址")
city = models.ForeignKey(CityDict, verbose_name=u"所在城市")
add_time = models.DateTimeField(default=datetime.now) class Meta:
verbose_name = u"课程机构"
verbose_name_plural = verbose_name class Teacher(models.Model):
org = models.ForeignKey(CourseOrg, verbose_name=u"所属机构")
name = models.CharField(max_length=50, verbose_name=u"教师名")
work_years = models.IntegerField(default=0, verbose_name=u"工作年限")
work_company = models.CharField(max_length=50, verbose_name=u"就职公司")
work_position = models.CharField(max_length=50, verbose_name=u"公司职位")
points = models.CharField(max_length=50, verbose_name=u"教学特点")
click_nums = models.IntegerField(default=0, verbose_name=u"点击数")
fav_nums = models.IntegerField(default=0, verbose_name=u"收藏数")
add_time = models.DateTimeField(default=datetime.now) class Meta:
verbose_name = u"教师"
verbose_name_plural = verbose_name

PS:shebang编码标注;

4-9 operation models.pty设计

4.9.1 operation 应用的创建;

4.9.2 operation/models.py的编写;

4.9.3 最后在settings.py中进行INSTALLED_APPS的注册;

# Application definition

INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'users',
'courses',
'organization',
'operation',
]

operation/models.py;

# _*_ encoding:utf-8 _*_
from __future__ import unicode_literals from datetime import datetime from django.db import models from users.models import UserProfile
from courses.models import Course # Create your models here.
class UserAsk(models.Model):
name = models.CharField(max_length=20, verbose_name=u"姓名")
mobile = models.CharField(max_length=11, verbose_name=u"手机")
course_name = models.CharField(max_length=50, verbose_name=u"课程名")
add_time = models.DateTimeField(default=datetime.now, verbose_name=u"添加时间") class Meta:
verbose_name = u"用户咨询"
verbose_name_plural = verbose_name class CourseComments(models.Model):
"""课程评论"""
user = models.ForeignKey(UserProfile, verbose_name=u"用户")
course = models.ForeignKey(Course, verbose_name=u"课程")
comments = models.CharField(max_length=200, verbose_name=u"评论")
add_time = models.DateTimeField(default=datetime.now, verbose_name=u"添加时间") class Meta:
verbose_name = u"课程评论"
verbose_name_plural = verbose_name class UserFavorite(models.Model):
user = models.ForeignKey(UserProfile, verbose_name=u"用户")
fav_id = models.IntegerField(default=0, verbose_name=u"数据ID")
fav_type = models.IntegerField(choices=((1, "课程"), (2, "课程结构"), (3, "讲师")), default=1, verbose_name=u"收藏类型")
add_time = models.DateTimeField(default=datetime.now, verbose_name=u"添加时间") class Meta:
verbose_name = u"用户收藏"
verbose_name_plural = verbose_name class UserMessage(models.Model):
user = models.IntegerField(default=0, verbose_name=u"接受用户")
message = models.CharField(default=datetime.now, verbose_name=u"消息内容")
has_read = models.BooleanField(default=False, verbose_name=u"是否已读")
add_time = models.DateTimeField(default=datetime.now, verbose_name=u"添加时间") class Meta:
verbose_name = u"用户消息"
verbose_name_plural = verbose_name class UserCourse(models.Model):
user = models.ForeignKey(UserProfile, verbose_name=u"用户")
course = models.ForeignKey(Course, verbose_name=u"课程")
add_time = models.DateTimeField(default=datetime.now, verbose_name=u"添加时间") class Meta:
verbose_name = u"用户课程"
verbose_name_plural = verbose_name 

4-10 数据表生成以及apps目录建立

4.10.1 Django中执行数据库迁移操作;

python manage.py makemigrations
python manage.py migrate

4.10.2 Django中的django_migrations表预览;

4.10.3 新建apps package,将所单独创立的应用移动至该目录;

4.10.4 settings.py中添加:sys.path.insert(0,os.path.join(BASE_DIR,'apps'));

import os
import sys # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0,os.path.join(BASE_DIR,'apps'))

第 5 章 通过xadmin快速搭建后台管理系统

5-1 Django admin介绍

5.1.1 后台管理系统的特点;

  • 权限管理;
  • 少前端样式;
  • 快速开发的需求;

5.1.2 createsuperuser创建超级用户时候的报错处理;

django.db.utils.DataError: (1406, u"Data too long for column 'gender' at row 1")

1、修改gender字段的max_lenth= xxx;
2、执行数据库迁移操作:
makemigrations users
migrate users

5.1.3 解决Django报错问题-Django admin 产生'WSGIRequest' object has no attribute 'user'的错误;

实际上,这是Django版本的问题,1.10之前,中间件的key为MIDDLEWARE_CLASSES, 1.10之后,为MIDDLEWARE。所以在开发环境和其他环境的版本不一致时,要特别小心,会有坑。
改配置为:

新的settings.py配置文件如下:

MIDDLEWARE_CLASSES = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

5.1.4 Django默认的登录方式,可以修改为支持用户名和邮箱登录;

5.1.5 修改Django的settings.py配置文件下的关键3项,使得admin页面显示中文;

  • LANGUAGE_CODE = 'zh-hans',之前叫做zh-cn;
  • TIME_ZONE = 'Asia/Shanghai'
  • USE_TZ = False

5.1.6 Django admin中组的概念初识以及在admin.py中进行注册;

  • Django的密码是单向的,不能反解答;

5-2 xadmin的安装

5.2.1 xadmin的安装;pip install xadmin(已存放在pypi中)

xadmin官网: http://sshwsfc.github.io/xadmin/#

  • django-crispy-forms-1.7.2
  • django-formtools-2.1
  • httplib2-0.9.2 xadmin-0.6.1

5.2.2 xadmin位于settings.py以及admin.py中的配置;

  • xadmin;
  • crispy_forms;
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'users',
'courses',
'organization',
'operation',
'xadmin',
'crispy_forms',
]

5.2.3 浏览器中访问xadmin的错误解决办法:执行数据库迁移操作makemigrations & migrate,生成xadmin相关的数据表;

5.2.4 去github.com上所有xadmin并下载zip文件;

5.2.5 解压缩xadmin-master.zip文件,拷贝其中xadmin至MxOnline的根目录;

5.2.6 在MxOnline项目中新建extra_apps package,将xadmin拷贝至其中;

5.2.6 Django+xadmin ImportError: No module named 'future'的报错解决方案

在使用Django框架时,集成xadmin后,运行程序,报如下这个错:importError:No module named future.utils这是因为没安装future,
因此,执行一下如下命令安装相关依赖包即可:
1、pip install future six httplib2
2、pip install django-import-export

5.2.7 Django 运行 端口被占用 Error: That port is already in use 的解决方案:

ps aux | grep -i manage

kill -9 端口号

5.2.8 源码安装xadmin以及pip install xadmin;推荐使用源码安装,好处是:体验新功能,修改源码提高程序可拓展性;

5-3 users app的model注册

5.3.1 users/models.py的注册;

5.3.2 新建adminx.py文件并进行邮箱验证码的注册;

5.3.3 重载了__unicode__(self):方法,return返回code和email

5.3.4 在adminx.py中增加新的字段——list_display以及search_fields字段;

5.3.5 在adminx.py完成各个models的注册工作;

adminx.py;

#!/usr/bin/python3
# -*- coding:utf-8 -*-
# Project: MxOnline
# Software: PyCharm
# Time : 2018-09-26 11:18
# File : adminx.py
# Author : 天晴天朗
# Email : tqtl@tqtl.org
import xadmin
from .models import EmailVerifyRecord, Banner class EmailVerifyRecordAdmin(object):
list_display = ['code', 'email', 'send_type', 'send_time']
search_fields = ['code', 'email', 'send_type', 'send_time']
list_filter = ['code', 'email', 'send_type', 'send_time'] class BannerAdmin(object):
list_display = ['title', 'image', 'url', 'index', 'add_time']
search_fields = ['title', 'image', 'url', 'index']
list_filter = ['title', 'image', 'url', 'index', 'add_time'] xadmin.site.register(EmailVerifyRecord, EmailVerifyRecordAdmin)
xadmin.site.register(Banner, BannerAdmin)

class EmailVerifyRecord(models.Model):
code = models.CharField(max_length=20, verbose_name=u'验证码')
email = models.EmailField(max_length=50, verbose_name=u'邮箱')
send_type = models.CharField(choices=(("register", u"注册"), ("forget", u"找回密码")), max_length=10,
verbose_name=u"验证码类型")
send_time = models.DateTimeField(default=datetime.now, verbose_name=u"发送时间") # datetime.now()不添加括号 class Meta:
verbose_name = u"邮箱验证码"
verbose_name_plural = verbose_name def __unicode__(self):
return '{0}({1})'.format(self.code, self.email)

5-4 剩余app model注册

5.4.1 在其他app下新建adminx.py,注意这个文件必须叫做adminx.py!!!

5.4.2 导入xadmin模块并进行注册;

5.4.3 字段中verbose_name的设置;

5.4.4 快速注册其他apps;

注意注意:注册之后一定要重启Django项目MxOnline!!!否则你是看不到滴!!!

xadmin.site.register注册的顺序就是在前端页面展示的顺序;

5-5 xadmin的全局配置

5.5.1 xadmin的主题功能配置;

5.5.2 左上角logo以及网页标题、底部显示内容设置,基于类;

5.5.3 设置参数menu_style = "accordion",将应用下的内容收缩;

5.5.4 Django创建app后,会在目录下自动生成apps.py,在此处设置展示的语言;

5.5.5 shebang位置添加# _*_ coding:utf-8 _*_;

5.5.6 分别在应用下apps.py 以及__init__.py中添加配置;

default_app_config = "courses.apps.CoursesConfig"
# _*_ coding:utf-8 _*_
from __future__ import unicode_literals from django.apps import AppConfig class UsersConfig(AppConfig):
name = 'users'
verbose_name = u"用户操作"

注意啦!我要讲话了,在Python2.x 中,但是要是出现中文的地方,记得一定在shebang位置添加 # _*_ coding:utf-8 _*_;

注意啦!我要讲话了,在Python2.x 中,但是要是出现中文的地方,记得一定在shebang位置添加 # _*_ coding:utf-8 _*_;

注意啦!我要讲话了,在Python2.x 中,但是要是出现中文的地方,记得一定在shebang位置添加 # _*_ coding:utf-8 _*_;

重要的话讲三遍!

第 6 章 用户注册功能实现

6-1 首页和登录页面的配置

6.1.1 在Django项目中新建static目录,并在settings.py中配置STATICFILES_DIRS  = []

6.1.2 拷贝静态文件如js\css\images\img等文件之static目录;

6.1.3 配置url访问路径;

6.1.4 拷贝前端同事的代码,比如index.html,login.html到templates目录下;

from django.conf.urls import url
from django.contrib import admin
from django.views.generic import TemplateView
import xadmin urlpatterns = [
url(r'^xadmin/', xadmin.site.urls),
url(r'^$', TemplateView.as_view(template_name="index.html"),name="index"),
url(r'^login/$', TemplateView.as_view(template_name="login.html"),name="login"),
]

6.1.4 settings.py中引入如下内容:

# Application definition
AUTHENTICATION_BACKENDS = (
'users.views.CustomBackend',
)
from django.conf.urls import url
from django.contrib import admin
from django.views.generic import TemplateView
import xadmin urlpatterns = [
url(r'^xadmin/', xadmin.site.urls),
url(r'^$', TemplateView.as_view(template_name="index.html"),name="index"),
url(r'^login/$', TemplateView.as_view(template_name="login.html"),name="login"),
]

6-2 用户登录-1

6.2.1 编写后台views逻辑代码;

6.2.2 Django防止CSRF攻击,使用{% csrf_token %}

6.2.3 Django模板中不会有很复杂的逻辑,更深层次的逻辑在后端代码中实现;

views.py;

# _*_ coding:utf-8 _*_
from django.shortcuts import render
from django.contrib.auth import authenticate, login
from django.contrib.auth.backends import ModelBackend
from django.db.models import Q
from .models import UserProfile # Create your views here.
class CustomBackend(ModelBackend):
def authenticate(self, username=None, password=None, **kwargs):
try:
user = UserProfile.objects.get(Q(username=username) | Q(email=username))
if user.check_password(password):
return user
except Exception as e:
return None def user_login(request):
if request.method == "POST":
username = request.POST.get("username", "")
password = request.POST.get("password", "")
user = authenticate(username=username, password=password)
# 完成login的认证登录;
if user is not None:
login(request, user)
return render(request, "index.html")
else:
return render(request, "login.html", {"msg":"用户名或者密码错误!"})
elif request.method == "GET":
return render(request, "login.html", {})

6-3 用户登录-2

  6.3.1在settings.py中添加参数:

  6.3.2基于类的形式编写用户登录功能;

  6.3.3 Django的密码存储的是密文使用check_password进行验证;

6-4 用form实现登录-1

  6.4.1  基于类的形式实现类的登录;

  6.4.2 LoginView.as_view();必须加括号!

urls.py;

"""MxOnline URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/1.11/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: url(r'^$', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.conf.urls import url, include
2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls'))
"""
from django.conf.urls import url
from django.contrib import admin
from django.views.generic import TemplateView
import xadmin
from users.views import LoginView urlpatterns = [
url(r'^xadmin/', xadmin.site.urls),
url(r'^$', TemplateView.as_view(template_name="index.html"), name="index"),
url('^login/$', LoginView.as_view(), name="login"),
]

views.py;

# _*_ coding:utf-8 _*_
from django.shortcuts import render
from django.contrib.auth import authenticate, login
from django.contrib.auth.backends import ModelBackend
from django.db.models import Q
from django.views.generic.base import View from .models import UserProfile
from .forms import LoginForm # Create your views here.
class CustomBackend(ModelBackend):
def authenticate(self, username=None, password=None, **kwargs):
try:
user = UserProfile.objects.get(Q(username=username) | Q(email=username))
if user.check_password(password):
return user
except Exception as e:
return None class LoginView(View):
def get(self, request):
return render(request, "login.html", {}) def post(self, request):
login_form = LoginForm(request.POST)
if login_form.is_valid():
user_name = request.POST.get("username", "")
pass_word = request.POST.get("password", "")
user = authenticate(username=user_name, password=pass_word)
if user is not None:
login(request, user)
return render(request, "index.html")
else:
return render(request, "login.html", {"msg": "用户名或密码错误"})
else:
return render(request, "login.html", {"login_form": login_form})

6-5 用form实现登录-2

6-6 session和cookie自动登录机制

6.6.1  cookies(浏览器本地存储方式),HTTP协议本身无状态;

6.6.2 session可以理解为服务端的cookie;

小结:

  • HTTP协议本身无状态保存;
  • 为了保存浏览器的一些信息,比如用户名和密码,引入了cookie机制;
  • 但是cookie是有服务端生成返回给客户端即浏览器的,保存在浏览器本地,不太安全;
  • 所以引出了服务端信息,session即服务端的cookie;
  • PS:cookie可以理解为保存会话信息的一个键值对;

6-7 用户注册-1

 6.7.1 图片验证码模块django-simple-captcha的Document;注意版本号——pip install django-simple-captcha==0.4.6 https://django-simple-captcha.readthedocs.io/en/latest/usage.html#installation

 6.7.2 django验证码框架(django-simple-captcha)的使用:

#!/usr/bin/python3
# -*- coding:utf-8 -*-
# Project: MxOnline
# Software: PyCharm
# Time : 2018-09-26 22:45
# File : forms.py
# Author : 天晴天朗
# Email : tqtl@tqtl.org
from django import forms
from captcha.fields import CaptchaField class LoginForm(forms.Form):
username = forms.CharField(required=True)
password = forms.CharField(required=True, min_length=5) class RegisterForm(forms.Form):
email = forms.EmailField(required=True)
password = forms.CharField(required=True, min_length=5)
captcha = CaptchaField()

6-8 用户注册-2

  6.8.1 django-simple-captcha==0.4.6的效果展示;

6-9 用户注册-3

  6.9.1 settings中配置发送邮件配置;

EMAIL_HOST = "smtp.mxhichina.com"
EMAIL_PORT = 25
EMAIL_HOST_USER = "tqtl@tqtl.org"
EMAIL_HOST_PASSWORD = "fdsfad."
EMAIL_USE_TLS = False
EMAIL_FROM = "tqtl@tqtl.org"

  6.9.2 app下创建utils目录,并新增send_mail.py文件;

send_mail.py;

#!/usr/bin/python3
# -*- coding:utf-8 -*-
# Project: MxOnline
# Software: PyCharm
# Time : 2018-09-27 18:41
# File : email_send.py
# Author : 天晴天朗
# Email : tqtl@tqtl.org from users.models import EmailVerifyRecord
from random import Random
from django.core.mail import send_mail
from MxOnline.settings import EMAIL_FROM def random_str(randomlength=8):
str = ''
chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz01234567890'
length = len(chars) - 1
random = Random()
for i in range(randomlength):
str += chars[random.randint(0, length)]
return str def send_register_email(email, send_type="register"):
email_record = EmailVerifyRecord()
code = random_str(16)
email_record.code = code
email_record.email = email
email_record.send_type = send_type
email_record.save() email_title = ""
email_body = ""
if send_type == "register":
email_title = "慕学在线网注册激活链接"
email_body = "请点击下面的链接来激活你的账号:http://127.0.0.1:8000/active/{0}".format(code)
send_status = send_mail(email_title, email_body, EMAIL_FROM, [email])
if send_status:
pass def generate_random_str():
pass

6-10 用户注册-4

6-11 找回密码(1)

6-12 找回密码(2)

第 7 章 课程机构功能实现

7-1 Django templates模板继承1

7.1.1 base.html模板编写;

base.html;

<!DOCTYPE html>
<html>
{% load staticfiles %}
<head>
<meta charset="UTF-8">
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
<title>{% block title %}课程机构列表 - 慕学在线网{% endblock %}</title>
<link rel="stylesheet" type="text/css" href="{% static 'css/reset.css' %}">
<link rel="stylesheet" type="text/css" href="{% static 'css/reset.css' %}">
<link rel="stylesheet" type="text/css" href="{% static 'css/reset.css' %}">
{% block custom_css %}{% endblock %}
<script src="{% static 'js/jquery.min.js' %}" type="text/javascript"></script>
<script src="{% static 'js/jquery-migrate-1.2.1.min.js' %}" type="text/javascript"></script>
{% block custom_js %}{% endblock %}
</head>
<body>
<section class="headerwrap ">
<header>
<div class=" header">
<div class="top">
<div class="wp">
<div class="fl"><p>服务电话:<b>33333333</b></p></div>
<!--登录后跳转--> <a style="color:white" class="fr registerbtn" href="register.html">注册</a>
<a style="color:white" class="fr loginbtn" href="login.html">登录</a> </div>
</div> <div class="middle">
<div class="wp">
<a href="index.html"><img class="fl" src="{% static 'images/logo.jpg' %}"/></a>
<div class="searchbox fr">
<div class="selectContainer fl">
<span class="selectOption" id="jsSelectOption" data-value="course">
公开课
</span>
<ul class="selectMenu" id="jsSelectMenu">
<li data-value="course">公开课</li>
<li data-value="org">课程机构</li>
<li data-value="teacher">授课老师</li>
</ul>
</div>
<input id="search_keywords" class="fl" type="text" value="" placeholder="请输入搜索内容"/>
<img class="search_btn fr" id="jsSearchBtn" src="{% static 'images/search_btn.png' %}"/>
</div>
</div>
</div> <nav>
<div class="nav">
<div class="wp">
<ul>
<li><a href="index.html">首页</a></li>
<li>
<a href="course-list.html">
公开课<img class="hot" src="{% static 'images/nav_hot.png' %}">
</a>
</li>
<li>
<a href="teachers-list.html">授课教师</a>
</li>
<li class="active"><a href="org-list.html">授课机构</a></li>
</ul>
</div>
</div>
</nav> </div>
</header>
</section>
<!--crumbs start-->
{% block custem_bread %}
<section>
<div class="wp">
<ul class="crumbs">
<li><a href="index.html">首页</a>></li>
<li>课程机构</li>
</ul>
</div>
</section>
{% endblock %}
{% block content %}
<section>
<div class="wp butler_list_box list">
<div class='left'>
<div class="listoptions">
<ul>
<li>
<h2>机构类别</h2>
<div class="cont">
<a href="?city="><span class="active2">全部</span></a> <a href="?ct=pxjg&city="><span class="">培训机构</span></a> <a href="?ct=gx&city="><span class="">高校</span></a> <a href="?ct=gr&city="><span class="">个人</span></a> </div>
</li>
<li>
<h2>所在地区</h2>
<div class="more">更多</div>
<div class="cont">
<a href="?ct="><span class="active2">全部</span></a> <a href="?city=1&ct="><span class="">北京市</span></a> <a href="?city=2&ct="><span class="">上海市</span></a> <a href="?city=3&ct="><span class="">广州市</span></a> <a href="?city=4&ct="><span class="">深圳市</span></a> <a href="?city=5&ct="><span class="">天津市</span></a> </div>
</li>
</ul>
</div>
<div class="all">共<span class="key">15</span>家</div>
<div class="butler_list company list">
<div class="layout">
<div class="head">
<ul class="tab_header">
<li class="active"><a href="?ct=&city=">全部</a></li>
<li class=""><a href="?sort=students&ct=&city=">学习人数 &#8595;</a></li>
<li class=""><a href="?sort=courses&ct=&city=">课程数 &#8595;</a></li>
</ul>
</div> <dl class="des difdes">
<dt>
<a href="org-detail-homepage.html">
<img width="" height="" class="scrollLoading"
data-url="../media/org/2016/11/imooc.png"/>
</a>
</dt>
<dd>
<div class="clearfix">
<a href="org-detail-homepage.html">
<h1>慕课网</h1>
<div class="pic fl"> <img src="../images/authentication.png"/> <img src="../images/gold.png"/> </div>
</a>
</div>
<ul class="cont">
<li class="first"><p class="pic9">课程数:<span>1</span></p>
<p class="c7">学习人数:<span>1000</span></p></li>
<li class="c8" style="padding-left:18px;">北京市海淀区中关村北大街</li>
<li class="pic10" style="padding-left:18px;">经典课程: <a href="/diary/19/">c语言基础入门</a> <a href="/diary/16/">数据库基础</a> </li>
</ul>
</dd>
<div class="buy start_groupbuy jsShowPerfect2" data-id=""><br/>联系<br/>服务</div>
</dl> <dl class="des difdes">
<dt>
<a href="org-detail-homepage.html">
<img width="" height="" class="scrollLoading"
data-url="../media/org/2016/11/bjdx.jpg"/>
</a>
</dt>
<dd>
<div class="clearfix">
<a href="org-detail-homepage.html">
<h1>北京大学</h1>
<div class="pic fl"> <img src="../images/authentication.png"/> <img src="../images/gold.png"/> </div>
</a>
</div>
<ul class="cont">
<li class="first"><p class="pic9">课程数:<span>1</span></p>
<p class="c7">学习人数:<span>1000</span></p></li>
<li class="c8" style="padding-left:18px;">北京市海淀区中关村北大街</li>
<li class="pic10" style="padding-left:18px;">经典课程: <a href="/diary/19/">c语言基础入门</a> <a href="/diary/16/">数据库基础</a> </li>
</ul>
</dd>
<div class="buy start_groupbuy jsShowPerfect2" data-id=""><br/>联系<br/>服务</div>
</dl> <dl class="des difdes">
<dt>
<a href="org-detail-homepage.html">
<img width="" height="" class="scrollLoading"
data-url="../media/org/2016/11/qhdx-logo.png"/>
</a>
</dt>
<dd>
<div class="clearfix">
<a href="org-detail-homepage.html">
<h1>清华大学</h1>
<div class="pic fl"> <img src="../images/authentication.png"/> <img src="../images/gold.png"/> </div>
</a>
</div>
<ul class="cont">
<li class="first"><p class="pic9">课程数:<span>1</span></p>
<p class="c7">学习人数:<span>1000</span></p></li>
<li class="c8" style="padding-left:18px;">北京市海淀区中关村北大街</li>
<li class="pic10" style="padding-left:18px;">经典课程: <a href="/diary/19/">c语言基础入门</a> <a href="/diary/16/">数据库基础</a> </li>
</ul>
</dd>
<div class="buy start_groupbuy jsShowPerfect2" data-id=""><br/>联系<br/>服务</div>
</dl> <dl class="des difdes">
<dt>
<a href="org-detail-homepage.html">
<img width="" height="" class="scrollLoading"
data-url="../media/org/2016/11/njdx.jpg"/>
</a>
</dt>
<dd>
<div class="clearfix">
<a href="org-detail-homepage.html">
<h1>南京大学</h1>
<div class="pic fl"> <img src="../images/authentication.png"/> <img src="../images/gold.png"/> </div>
</a>
</div>
<ul class="cont">
<li class="first"><p class="pic9">课程数:<span>1</span></p>
<p class="c7">学习人数:<span>1000</span></p></li>
<li class="c8" style="padding-left:18px;">北京市海淀区中关村北大街</li>
<li class="pic10" style="padding-left:18px;">经典课程: <a href="/diary/19/">c语言基础入门</a> <a href="/diary/16/">数据库基础</a> </li>
</ul>
</dd>
<div class="buy start_groupbuy jsShowPerfect2" data-id=""><br/>联系<br/>服务</div>
</dl> <dl class="des difdes">
<dt>
<a href="org-detail-homepage.html">
<img width="" height="" class="scrollLoading"
data-url="../media/org/2016/11/imooc_klgAUn5.png"/>
</a>
</dt>
<dd>
<div class="clearfix">
<a href="org-detail-homepage.html">
<h1>慕课网2</h1>
<div class="pic fl"> <img src="../images/authentication.png"/> <img src="../images/gold.png"/> </div>
</a>
</div>
<ul class="cont">
<li class="first"><p class="pic9">课程数:<span>1</span></p>
<p class="c7">学习人数:<span>1000</span></p></li>
<li class="c8" style="padding-left:18px;">北京市海淀区中关村北大街</li>
<li class="pic10" style="padding-left:18px;">经典课程: <a href="/diary/19/">c语言基础入门</a> <a href="/diary/16/">数据库基础</a> </li>
</ul>
</dd>
<div class="buy start_groupbuy jsShowPerfect2" data-id=""><br/>联系<br/>服务</div>
</dl> </div>
<div class="pageturn">
<ul class="pagelist"> <li class="active"><a href="?page=1">1</a></li> <li><a href="?page=2" class="page">2</a></li> <li><a href="?page=3" class="page">3</a></li> <li class="long"><a href="?page=2">下一页</a></li> </ul>
</div>
</div>
</div>
<div class="right companyright">
<div class="head">我要学习</div>
<form class="rightform" id="jsStayForm">
<div>
<img src="{% static 'images/rightform1.png' %}"/>
<input type="text" name="name" id="companyName" placeholder="名字" maxlength=""/>
</div>
<div>
<img src="{% static 'images/rightform2.png' %}"/>
<input type="text" name="mobile" id="companyMobile" placeholder="联系电话"/>
</div>
<div>
<img src="{% static 'images/rightform3.png' %}"/>
<input type="text" name="course_name" id="companyAddress" placeholder="课程名" maxlength=""/>
</div>
<p class="error company-tips" id="jsCompanyTips"></p>
<input class="btn" type="text" id="jsStayBtn" value="立即咨询 >"/>
</form>
</div> <div class="right companyrank layout">
<div class="head">授课机构排名</div> <dl class="des">
<dt class="num fl">1</dt>
<dd>
<a href="/company/2/"><h1>慕课网</h1></a>
<p>北京市</p>
</dd>
</dl> <dl class="des">
<dt class="num fl">2</dt>
<dd>
<a href="/company/2/"><h1>慕课网2</h1></a>
<p>深圳市</p>
</dd>
</dl> <dl class="des">
<dt class="num fl">3</dt>
<dd>
<a href="/company/2/"><h1>北京大学</h1></a>
<p>北京市</p>
</dd>
</dl> </div>
</div>
</section>
{% endblock %}
<footer>
<div class="footer">
<div class="wp">
<ul class="cont">
<li class="logo"><a href=""><img src="../images/footlogo.png"/></a></li>
<li class="code"><img src="../images/code.jpg"/>
<p class="center">扫描关注微信</p></li>
<li class="third"><img class="fl" src="../images/tell.png"/>
<p class="tell">33333333</p>
<p class="time">周一至周日 9:00-18:00</p></li>
</ul> </div>
<p class="line"></p>
<div class="wp clear">
<span class="fl">? 2016 www.projectsedu.com 慕学在线-在线学习交流平台 保留所有权利</span>
<span class="fr">copyright ? 2016 ICP备案证书号:蜀ICP备xxxxx号-1</span>
</div>
</div>
</footer> <section>
<ul class="sidebar">
<li class="qq">
<a target="_blank" href="http://wpa.qq.com/msgrd?v=3&uin=2023525077&site=qq&menu=yes"></a>
</li>
<li class="totop"></li>
</ul>
</section>
<script src="{% static 'js/selectUi.js' %}" type='text/javascript'></script>
<script src="{% static 'js/deco-common.js' %}" type='text/javascript'></script>
<script type="text/javascript" src="{% static 'js/plugins/laydate/laydate.js' %}"></script>
<script src="{% static 'js/plugins/layer/layer.js' %}"></script>
<script src="{% static 'js/plugins/queryCity/js/public.js' %}" type="text/javascript"></script>
<script src="{% static 'js/unslider.js' %}" type="text/javascript"></script>
<script src="{% static 'js/plugins/jquery.scrollLoading.js' %}" type="text/javascript"></script>
<script src="{% static 'js/deco-common.js' %}" type="text/javascript"></script> <script>
$(function () {
$(document).ready(function () {
$('#jsStayBtn').on('click', function () {
$.ajax({
cache: false,
type: "POST",
url: "/org/add_ask/",
data: $('#jsStayForm').serialize(),
async: true,
success: function (data) {
if (data.status == 'success') {
$('#jsStayForm')[0].reset();
alert("提交成功")
} else if (data.status == 'fail') {
$('#jsCompanyTips').html(data.msg)
}
},
});
});
});
}) </script> </body>
</html>

7-2 Django templates模板继承2

7.2.1 课程列表页的模板虽然继承了base.html,但是依然要引入{% load staticfiles %}

org-list.html

{% extends 'base.html' %}
{% load staticfiles %}
{% block title %}课程机构列表-慕学在线网首页{% endblock %}
{% block custem_bread %}
<section>
<div class="wp">
<ul class="crumbs">
<li><a href="index.html">首页</a>></li>
<li>课程机构</li>
</ul>
</div>
</section>
{% endblock %}
{% block content %}
<section>
<div class="wp butler_list_box list">
<div class='left'>
<div class="listoptions">
<ul>
<li>
<h2>机构类别</h2>
<div class="cont">
<a href="?city="><span class="active2">全部</span></a> <a href="?ct=pxjg&city="><span class="">培训机构</span></a> <a href="?ct=gx&city="><span class="">高校</span></a> <a href="?ct=gr&city="><span class="">个人</span></a> </div>
</li>
<li>
<h2>所在地区</h2>
<div class="more">更多</div>
<div class="cont">
<a href="?ct="><span class="active2">全部</span></a> <a href="?city=1&ct="><span class="">北京市</span></a> <a href="?city=2&ct="><span class="">上海市</span></a> <a href="?city=3&ct="><span class="">广州市</span></a> <a href="?city=4&ct="><span class="">深圳市</span></a> <a href="?city=5&ct="><span class="">天津市</span></a> </div>
</li>
</ul>
</div>
<div class="all">共<span class="key">15</span>家</div>
<div class="butler_list company list">
<div class="layout">
<div class="head">
<ul class="tab_header">
<li class="active"><a href="?ct=&city=">全部</a></li>
<li class=""><a href="?sort=students&ct=&city=">学习人数 ↓</a></li>
<li class=""><a href="?sort=courses&ct=&city=">课程数 ↓</a></li>
</ul>
</div> <dl class="des difdes">
<dt>
<a href="org-detail-homepage.html">
<img width="200" height="120" class="scrollLoading"
data-url="{% static 'media/org/2016/11/imooc.png' %}"/>
</a>
</dt>
<dd>
<div class="clearfix">
<a href="org-detail-homepage.html">
<h1>慕课网</h1>
<div class="pic fl"> <img src="{% static 'images/authentication.png' %}"/> <img src="{% static 'images/gold.png' %}"/> </div>
</a>
</div>
<ul class="cont">
<li class="first"><p class="pic9">课程数:<span>1</span></p>
<p class="c7">学习人数:<span>1000</span></p></li>
<li class="c8" style="padding-left:18px;">北京市海淀区中关村北大街</li>
<li class="pic10" style="padding-left:18px;">经典课程: <a href="/diary/19/">c语言基础入门</a> <a href="/diary/16/">数据库基础</a> </li>
</ul>
</dd>
<div class="buy start_groupbuy jsShowPerfect2" data-id="22"><br/>联系<br/>服务</div>
</dl> <dl class="des difdes">
<dt>
<a href="org-detail-homepage.html">
<img width="200" height="120" class="scrollLoading"
data-url="{% static 'media/org/2016/11/bjdx.jpg' %}"/>
</a>
</dt>
<dd>
<div class="clearfix">
<a href="org-detail-homepage.html">
<h1>北京大学</h1>
<div class="pic fl"> <img src="{% static 'images/authentication.png' %}"/> <img src="{% static 'images/gold.png' %}"/> </div>
</a>
</div>
<ul class="cont">
<li class="first"><p class="pic9">课程数:<span>1</span></p>
<p class="c7">学习人数:<span>1000</span></p></li>
<li class="c8" style="padding-left:18px;">北京市海淀区中关村北大街</li>
<li class="pic10" style="padding-left:18px;">经典课程: <a href="/diary/19/">c语言基础入门</a> <a href="/diary/16/">数据库基础</a> </li>
</ul>
</dd>
<div class="buy start_groupbuy jsShowPerfect2" data-id="22"><br/>联系<br/>服务</div>
</dl> <dl class="des difdes">
<dt>
<a href="org-detail-homepage.html">
<img width="200" height="120" class="scrollLoading"
data-url="{% static 'media/org/2016/11/qhdx-logo.png' %}"/>
</a>
</dt>
<dd>
<div class="clearfix">
<a href="org-detail-homepage.html">
<h1>清华大学</h1>
<div class="pic fl"> <img src="{% static 'images/authentication.png' %}"/> <img src="{% static 'images/gold.png' %}"/> </div>
</a>
</div>
<ul class="cont">
<li class="first"><p class="pic9">课程数:<span>1</span></p>
<p class="c7">学习人数:<span>1000</span></p></li>
<li class="c8" style="padding-left:18px;">北京市海淀区中关村北大街</li>
<li class="pic10" style="padding-left:18px;">经典课程: <a href="/diary/19/">c语言基础入门</a> <a href="/diary/16/">数据库基础</a> </li>
</ul>
</dd>
<div class="buy start_groupbuy jsShowPerfect2" data-id="22"><br/>联系<br/>服务</div>
</dl> <dl class="des difdes">
<dt>
<a href="org-detail-homepage.html">
<img width="200" height="120" class="scrollLoading"
data-url="{% static 'media/org/2016/11/njdx.jpg' %}"/>
</a>
</dt>
<dd>
<div class="clearfix">
<a href="org-detail-homepage.html">
<h1>南京大学</h1>
<div class="pic fl"> <img src="{% static 'images/authentication.png' %}"/> <img src="{% static 'images/gold.png' %}"/> </div>
</a>
</div>
<ul class="cont">
<li class="first"><p class="pic9">课程数:<span>1</span></p>
<p class="c7">学习人数:<span>1000</span></p></li>
<li class="c8" style="padding-left:18px;">北京市海淀区中关村北大街</li>
<li class="pic10" style="padding-left:18px;">经典课程: <a href="/diary/19/">c语言基础入门</a> <a href="/diary/16/">数据库基础</a> </li>
</ul>
</dd>
<div class="buy start_groupbuy jsShowPerfect2" data-id="22"><br/>联系<br/>服务</div>
</dl> <dl class="des difdes">
<dt>
<a href="org-detail-homepage.html">
<img width="200" height="120" class="scrollLoading"
data-url="{% static 'media/org/2016/11/imooc_klgAUn5.png' %}"/>
</a>
</dt>
<dd>
<div class="clearfix">
<a href="org-detail-homepage.html">
<h1>慕课网2</h1>
<div class="pic fl"> <img src="{% static 'images/authentication.png' %}"/> <img src="{% static 'images/gold.png' %}"/> </div>
</a>
</div>
<ul class="cont">
<li class="first"><p class="pic9">课程数:<span>1</span></p>
<p class="c7">学习人数:<span>1000</span></p></li>
<li class="c8" style="padding-left:18px;">北京市海淀区中关村北大街</li>
<li class="pic10" style="padding-left:18px;">经典课程: <a href="/diary/19/">c语言基础入门</a> <a href="/diary/16/">数据库基础</a> </li>
</ul>
</dd>
<div class="buy start_groupbuy jsShowPerfect2" data-id="22"><br/>联系<br/>服务</div>
</dl> </div>
<div class="pageturn">
<ul class="pagelist"> <li class="active"><a href="?page=1">1</a></li> <li><a href="?page=2" class="page">2</a></li> <li><a href="?page=3" class="page">3</a></li> <li class="long"><a href="?page=2">下一页</a></li> </ul>
</div>
</div>
</div>
<div class="right companyright">
<div class="head">我要学习</div>
<form class="rightform" id="jsStayForm">
<div>
<img src="{% static 'images/rightform1.png' %}"/>
<input type="text" name="name" id="companyName" placeholder="名字" maxlength="25"/>
</div>
<div>
<img src="{% static 'images/rightform2.png' %}"/>
<input type="text" name="mobile" id="companyMobile" placeholder="联系电话"/>
</div>
<div>
<img src="{% static 'images/rightform3.png' %}"/>
<input type="text" name="course_name" id="companyAddress" placeholder="课程名" maxlength="50"/>
</div>
<p class="error company-tips" id="jsCompanyTips"></p>
<input class="btn" type="text" id="jsStayBtn" value="立即咨询 >"/>
</form>
</div> <div class="right companyrank layout">
<div class="head">授课机构排名</div> <dl class="des">
<dt class="num fl">1</dt>
<dd>
<a href="/company/2/"><h1>慕课网</h1></a>
<p>北京市</p>
</dd>
</dl> <dl class="des">
<dt class="num fl">2</dt>
<dd>
<a href="/company/2/"><h1>慕课网2</h1></a>
<p>深圳市</p>
</dd>
</dl> <dl class="des">
<dt class="num fl">3</dt>
<dd>
<a href="/company/2/"><h1>北京大学</h1></a>
<p>北京市</p>
</dd>
</dl> </div>
</div>
</section>
{% endblock %}

7-3 课程机构列表页数据展示1

7.3.1 https://github.com/jamespacileo/django-pure-pagination 分页库的使用;

views.py;

# _*_ coding:utf-8 _*_
from django.shortcuts import render
from django.views.generic import View from .models import CourseOrg, CityDict
from pure_pagination import Paginator, EmptyPage, PageNotAnInteger # Create your views here.
class OrgView(View):
"""
课程机构列表功能
""" def get(self, request):
# 课程机构
all_orgs = CourseOrg.objects.all()
org_nums = all_orgs.count()
# 城市
all_citys = CityDict.objects.all()
# 对课程机构进行分页;
try:
page = request.GET.get('page', 1)
except PageNotAnInteger:
page = 1 p = Paginator(all_orgs, 2, request=request) orgs = p.page(page) return render(request, "org-list.html", {
"all_orgs": orgs,
"all_citys": all_citys,
"org_nums": org_nums,
})

org-list.html

</div>
<div class="pageturn">
<ul class="pagelist">
{% if all_orgs.has_previous %}
<li class="long"><a href="?{{ all_orgs.previous_page_number.querystring }}">上一页</a></li>
{% endif %} {% for page in all_orgs.pages %}
{% if page %}
{% ifequal page all_orgs.number %}
<li class="active"><a href="?{{ page.querystring }}">{{ page }}</a></li>
{% else %}
<li><a href="?{{ page.querystring }}" class="page">{{ page }}</a></li>
{% endifequal %}
{% else %}
<li class="none"><a href="">...</a></li>
{% endif %}
{% endfor %}
{% if all_orgs.has_next %}
<li class="long"><a href="?{{ all_orgs.next_page_number.querystring }}">下一页</a></li>
{% endif %}
</ul>
</div>

7-4 课程机构列表数据展示2

7.4.1 数据要展示在templates中;

7-5 列表分页功能

7-6 列表筛选功能

7-7 modelform提交我要学习咨询1

7-8 modelform提交我要学习咨询2

7-9 机构详情展示-1

7-10 结构详情展示-2

7-11 机构详情展示-3

7-12 课程机构收藏功能

第 8 章 课程功能展示

8-1 课程列表

8.1.1 课程列表页的展示;

8.1.2 分页功能的开发;

8.1.3 推荐课程的开发;

8-2 课程详情页1

8.2.1 课程详情页1

8-3 课程详情2

8.3.1 课程详情2

8-4 课程章节信息1

8.4.1 课程章节信息展示

8-5 课程章节信息2

8-6 课程评论功能

8.6.1 课程的评论功能开发;

8-7 相关课程推荐

8-8 视频播放页面

第 9 章 课程讲师功能实现

9-1 讲师列表页

9-2 讲师详情页1

9-3 讲师详情页2

第 10 章 个人中心和全局搜索功能实现

10-1 配置全局导航

10-2 全局搜索功能开发

10-3 个人信息展示

10-4 修改密码和修改头像1

10-5 修改密码和修改头像2

10-6 修改邮箱和用户信息1

10-7 修改邮箱和用户信息2

10-8 我的课程

10-9 我的收藏功能1

10-10 我的收藏功能2

10-11 我的消息

第 11 章 首页、全局功能细节和404以及500页面配置

11-1 登出和点击数以及收藏数完善

11-2 首页功能开发1

11-3 首页功能开发2

11-4 404和500页面配置

第 12 章 常见Web攻击即防范

12-1 SQL注入攻击与防范

12-2 XSS攻击原理及防范

12-3 CSRF攻击与防范

第 13 章 xadmin的进阶开发

13-1 Userprofile注册以及Django的权限管理1

13-2 Userprofile注册以及Django的权限管理2

13-3 model_ico,只读子字段、默认排序设置

13-4 自定义列表返回数据,同一个model注册两个管理器

13-5 xadmin其他常见功能的使用

13-6 xadmin继承富文本ueditor1

13-7 xadmin集成富文本ueditor2

13-8 excel导入插件介绍

第 14 章 把项目部署上线

14-1 Nginx、MySQL、Virtualenv的安装和配置

  • apt-get install nginx
  • apt-get install mysql-server
  • 修改MySQL支持远程连接;
  • 在Ubuntu18.04LTS的Linux发行版上安装virtualenv 和virtualenvwrapper
  • .bashrc文件中配置环境变量,如下:
  • source .bashrc使得配置立即生效;
export WORKON_HOME=$HOME/.virtualenvs

source /usr/local/bin/virtualenvwrapper.sh

14-2 uwsgi安装和启动、Nginx的虚拟主机配置

14-3 uwsgi配置文件方式启动一级代码更新后的重启

第 15 章 课程总结

15-1 课程总结

第 16 章 快速升级到Python3.6 + Django1.11

16-1 Python3.6 虚拟开发环境的搭建与开发包的安装

  • 创建虚拟环境,执行Python的版本;
  • mysqlcient替代python-mysql;
  • excel导出相关包;

16-2 修改代码适配Python3.6和Django1.11

  • 配置虚拟环境解释器;
  • xadmin&DjangoUeditor使用github资源;

第 17 章 快速升级到Python3.6 + Django2.0

17-1 快速升级到Python3.6 + Django2.0

django2.0开始只支持python3, 所以升级前确保之前是用django1.11和python3.6开发的,代码可以在相应分支获取

1. 安装依赖包
新装
pip install requests
重装
django-crispy-forms
django-formtools
django-import-export
django-simple-captcha
django-pure-pagination
2. 拷贝django2分支下的xadmin和djangoueditor源码 3. 所有model的外键需要加上on_delete的行为 改为 on_delete=models.CASCADE 4. from django.core.urlresolvers import reverse 全部改为 from django.urls import reverse 5. url中关于include的地方全部改为 url(r'^course/', include(('courses.urls','courses'), namespace="course"))的模式 6. 说明一下 urls.py中url(r'^captcha/', include('captcha.urls')), 一定不能加namespace也不能用上面的模式,保持原来模式就行了 7. 将settings中的MIDDLEWARE_CLASSES 改为 MIDDLEWARE并删除'django.contrib.auth.middleware.SessionAuthenticationMiddleware' 这一行 8. 课程中关于request.user.is_authenticated()中的地方要改为request.user.is_authenticated

Python升级3.6 强力Django+Xadmin打造在线教育平台的更多相关文章

  1. Django+xadmin打造在线教育平台(二)

    三.xadmin后台管理 3.1.xadmin的安装 django2.0的安装(源码安装方式): https://github.com/sshwsfc/xadmin/tree/django2 把zip ...

  2. Django+xadmin打造在线教育平台(三)

    五.完成注册.找回密码和激活验证码功能 5.1.用户注册 register.html拷贝到templates目录 (1)users/views.py class RegisterView(View): ...

  3. Django+xadmin打造在线教育平台(一)

    目录 在线教育平台(一)      在线教育平台(二) 在线教育平台(三)      在线教育平台(四) 在线教育平台(五)      在线教育平台(六) 在线教育平台(七)      在线教育平台( ...

  4. Django+xadmin打造在线教育平台(六)

    九.课程章节信息 9.1.模板和urls 拷贝course-comments.html 和 course-video.html放入 templates目录下 先改course-video.html,同 ...

  5. Django+xadmin打造在线教育平台(四)

    七.授课机构功能 7.1.模板继承 (1)创建母板 把org-list.html拷贝到templates目录下,新建base.html,剪切org-list.html内容到里面 再修改一下静态文件的地 ...

  6. Django+xadmin打造在线教育平台(七)

    十.授课教师 10.1.讲师列表页 拷贝teacher-list.html和teacher-detail.html到templates目录下 先改teacher-list.html,同样继承base. ...

  7. Django+xadmin打造在线教育平台(十)

    十四.xadmin的进阶开发 14.1.权限管理 (1)用户权限 超级用户拥有所有权限,其它添加的用户默认没有任何权限 进后台添加一个用户“Editor1”,勾上“职员状态”后,这个用户才可以登录进后 ...

  8. Django+xadmin打造在线教育平台(五)

    目录 在线教育平台(一)      在线教育平台(二) 在线教育平台(三)      在线教育平台(四) 在线教育平台(五)      在线教育平台(六) 在线教育平台(七)      在线教育平台( ...

  9. Django+xadmin打造在线教育平台(八)

    十一.用户信息 11.1.个人信息展示 (1)新建‘usercenter-bae.html’当母板 {% load staticfiles %} <!DOCTYPE html> <h ...

随机推荐

  1. 简单的使用git克隆上传创建下载删除

    首先我们下载个git 官网:https://git-scm.com/ 我这里下的是64-bit windows setup 下载完成后安装: 一直下一步就好 安装完成后进行打开! 现在我们需要去官网注 ...

  2. Android学习笔记_76_AsyncQueryHandler的应用

    研究AsyncQueryHandler这个类的时候遇到了几个重要的不清楚的知识点 1. Handler与Thread,Looper的关系 2. HandlerThread是干什么用的 3. Threa ...

  3. 消息中间件JMS(二)

    之前介绍了ActiveMQ下载与安装,并且启动了.下面进行ActiveMQ的Demo 1. JMS入门Demo 1.1 点对点模式 点对点模式主要建立在一个队列上面,当连接一个队列的时候,发送端不需要 ...

  4. 第10章 使用STM32CubeMX新建工程

    STM32Cube是一项意法半导体的原创活动, 通过减少开发工作.时间和成本, 使开发者的开发工作更轻松.STM32Cube 是一个全面的软件平台,包括了ST产品的每个系列.(如,STM32CubeF ...

  5. Introduction to CQRS

    原文链接:  http://www.codeproject.com/Articles/555855/Introduction-to-CQRS What is CQRS CQRS means Comma ...

  6. js图片预览(一张图片预览)

    核心思想:无论是一张图片上传还是多图上传,首先我们都需要先获得图片对象. 栗子: <inuput type="file" id="myfile" onch ...

  7. orcal 数据库 maven架构 ssh框架 的全注解环境模版 maven中央仓库批量删除lastupdated文件后依然是lastupdated解决方法 mirror aliyun中央仓库

    批量删除文件,得用批处理文件,文件名随便,路径改成你的Repository,代码如下 rem 这里写你的仓库路径 set REPOSITORY_PATH=d:\repo rem 正在搜索... for ...

  8. c#数据库连接池

    因为使用习惯的问题,我封装了一个数据库连接池Hikari,这是我自定义的数据库连接池.因为c#的连接池按照规范的ADO.NET里面实现定义的,由数据库官方提供,但是实现方式就不知道了,反正没有看出来, ...

  9. 更换eclipse字体

    eclipse自带的字体非常不好,看的我难受,可能是使用myeclipse习惯了,怎么调节都不好使 最后决定下载一个字体包吧! 字体下载地址如下:http://files.cnblogs.com/ic ...

  10. 肝题与oj

    oier很多,oj也很多,这些oj分别有怎样的特点,我们又该怎样选择呢?请各位客官听在下分解 (我主要说一些比较大众的oj) (注意:难度与界面友好度为个人意见,不喜勿喷) 1.入门级 1.NOIop ...