Python升級3.6 強力Django+Xadmin打造在線教育平臺

第 1 章 課程介紹

1-1 項目演示和課程介紹;

第 2 章 Windows下搭建開發環境

2-1 Pycharm、Navicat和Python解釋器的安裝;

 

 

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

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': '3306',
    }

}

# 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/css

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': '3306',
        '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 pillowhtml

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")

一、修改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配置文件以下:java

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/#python

  • 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,
所以,執行一下以下命令安裝相關依賴包便可:
一、pip install future six httplib2
二、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 _*_;

重要的話講三遍!mysql

 

第 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;jquery

小結:nginx

  • 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的效果展現;git

 

 

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="200" height="120" 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="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="../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="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="../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="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="../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="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="../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="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 %}
<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=">學習人數 &#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="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

 

相關文章
相關標籤/搜索