第四章 需求分析和Model設計
1、建立Django-APP
建立MxOnline Django項目
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnLxITLyQTLyIDMyUyNy0SMx0yNxAjMwITJt9mcmBjMlQ3boNnblVmcjN1LclDM5QTO18CXuNmLuVXeplXa1NnLn1Wavw1LcpDc0RHaiojIsJye.png)
擴充Django預設表達到自定義userprofile表的目的
建立users APP,==所有網站的設計應該都從users開始設計==
用makemigration和migrate指令建立預設資料庫,自動建立的使用者表為==auth_user==
編寫models.py檔案,==注意一定要寫utf-8格式==
#_*_ encoding:utf-8 _*_
from __future__ import unicode_literals
from django.db import models
from django.contrib.auth.models import AbstractUser
# Create your models here.
class UserProfile(AbstractUser):
nick_name = models.CharField(max_length=, verbose_name=u"昵稱", default="")
birthday = models.DateField(verbose_name=u"生日", null=True, blank=True)
gender = models.CharField(max_length=, choices=(("male",u"男"), ("female",u"女")), default="female")
address = models.CharField(max_length=, default=u"")
mobile = models.CharField(max_length=, null=True, blank=True)
image = models.ImageField(upload_to="image/%Y/%m",default=u"image/default.png", max_length=)
class Meta:
verbose_name = "使用者資訊"
verbose_name_plural = verbose_name
def __unicode__(self):
return self.username、
執行過程中出現此問題,需要傳回虛拟環境安裝==Pillow庫==
ERRORS:
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".
運作後提示
ValueError: Dependency on app with no migrations: users
此時要做一下users的migration,打開manage.py
[email protected] > makemigrations users
bash -cl "/home/liang/.virtualenvs/mxonline/bin/python2.7 /home/liang/pycharm-2017.2.4/helpers/pycharm/django_manage.py makemigrations users /home/liang/PycharmProjects/MxOnline"
Migrations for 'users':
[email protected] > migrate users
bash -cl "/home/liang/.virtualenvs/mxonline/bin/python2.7 /home/liang/pycharm-2017.2.4/helpers/pycharm/django_manage.py migrate users /home/liang/PycharmProjects/MxOnline"
Operations to perform:
Apply all migrations: users
Running migrations:
Rendering model states... DONE
Applying users_initial... OK
The following content types are stale and need to be deleted:
auth | user
Any objects related to these content types by a foreign key will also
be deleted. Are you sure you want to delete these content types?
If you're unsure, answer 'no'.
Type 'yes' to continue, or 'no' to cancel: yes
Process finished with exit code
再次打開資料庫的users_profile表,顯示建立成功
makemigrations隻是生成一個比對記錄,migrate才是把更改應用到資料庫當中。
user models.py設計
User models.py 和Courses models.py存在循環引用
解決循環import最常用的方法是分層設計:
1. django app設計
2. users models.py編寫
3. courses models.py編寫
4. organization models.py編寫
5. operaion models.py編寫(最上層)
users models.py
- 自定義usersprofile覆寫預設user表
- EmailVerifyRecord-郵箱驗證碼(儲存到資料庫中)
- PageBanner-輪播圖
編輯Django檔案時,應注意遵循PEP8規範的==導入順序==
#_*_ encoding:utf-8 _*_
#第一個區域,放Python自帶的包
from __future__ import unicode_literals
from datetime import datetime
#第二個區域,放第三方的包
from django.db import models
from django.contrib.auth.models import AbstractUser
# Create your models her第三個區域,自己定義的model
class UserProfile(AbstractUser):
nick_name = models.CharField(max_length=, verbose_name=u"昵稱", default="")
birthday = models.DateField(verbose_name=u"生日", null=True, blank=True)
gender = models.CharField(max_length=, choices=(("male",u"男"), ("female",u"女")), default="female")
address = models.CharField(max_length=, default=u"")
mobile = models.CharField(max_length=, null=True, blank=True)
image = models.ImageField(upload_to="image/%Y/%m",default=u"image/default.png", max_length=)
class Meta:
verbose_name = "使用者資訊"
verbose_name_plural = verbose_name
def __unicode__(self):
return self.username
class EmailVerifyRecord(models.Model):
code = models.CharField(max_length=, verbose_name=u"驗證碼")
email = models.EmailField(max_length=, verbose_name=u"郵箱")
send_type = models.CharField(choices=(("register",u"注冊"),("forget",u"找回密碼")),max_length=)
send_time = models.DateTimeField(default=datetime.now)
#now加括号的話會生成實際編譯的時間,不加括号的話生成類執行個體化的時間
class Meta:
verbose_name = u"郵箱驗證碼"
verbose_name_plural = verbose_name
class Banner(models.Model):
title = models.CharField(max_length=, verbose_name=u"标題")
image = models.ImageField(upload_to="banner/%Y/%m",verbose_name=u"輪播圖",max_length=)
#image在資料庫當中存取的是圖檔的路徑位址
url = models.URLField(max_length=, verbose_name=u"通路位址")
index = models.IntegerField(default=, verbose_name=u"順序")
add_time = models.DateTimeField(default=datetime.now, verbose_name=u"添加時間")
class Meta:#表的名字
verbose_name = u"輪播圖"
verbose_name_plural = verbose_name
形成以下結構圖:
courses models.py
設計内容:
- Course - 課程基本資訊
- Lesson - 章節資訊
- Video - 視訊
- CourseResource - 課程資源
課程存在多層嵌套關系
graph LR
課程-->章節
章節-->視訊
代碼如下:
#_*_ 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=, verbose_name=u"課程名")
desc = models.CharField(max_length=, verbose_name=u"課程描述")
detail = models.TextField(verbose_name=u"課程詳情")
degree = models.CharField(choices=(("cj",u"初級"),("zj",u"中級"),("gj",u"進階")),max_length=)
learn_times = models.IntegerField(default=, verbose_name=u"學習時長(分鐘數)")
students = models.IntegerField(default=, verbose_name=u"學習人數")
fav_nums = models.IntegerField(default=, verbose_name=u"收藏人數")
image = models.ImageField(upload_to="courses/%Y%m", verbose_name=u"封面數", max_length=)
click_nums = models.IntegerField(default=, 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=, 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, verbose_name=u"章節")
name = models.CharField(max_length=, 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=, verbose_name=u"視訊名")
download = models.FileField(upload_to="course/resource/%Y/%m", verbose_name=u"資源檔案", max_length=)
add_time = models.DateTimeField(default=datetime.now, verbose_name=u"添加時間")
class Meta:
verbose_name = u"課程資源"
verbose_name_plural = verbose_name
organization models.py 設計
課程機構結構如下:
1. CourseOrg - 課程機構基本資訊
2. Teacher - 教師基本資訊
3. CityDictionary - 城市資訊
#_*_ 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=, verbose_name=u"城市")
desc = models.CharField(max_length=, verbose_name=u"描述")
add_time = models.DateTimeField(default=datetime.now)
class Meta:
verbose_name =u"城市"
verbose_name_plural = verbose_name
class CourseOrg(models.Model):
name = models.CharField(max_length=, verbose_name=u"機構名稱")
desc = models.TextField(verbose_name=u"機構描述")
click_num = models.IntegerField(default=, verbose_name=u"點選數")
fav_nums = models.IntegerField(default=, verbose_name=u"收藏數")
image = models.ImageField(upload_to="org/%Y%m", verbose_name=u"封面數", max_length=)
address = models.CharField(max_length=,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=, verbose_name=u"教師名")
work_year = models.IntegerField(default=, verbose_name=u"工作年限")
work_company = models.CharField(max_length=, verbose_name=u"就職公司")
work_position = models.CharField(max_length=, verbose_name=u"公司職位")
points = models.CharField(max_length=, verbose_name=u"教學特點")
click_num = models.IntegerField(default=, verbose_name=u"點選數")
fav_nums = models.IntegerField(default=, verbose_name=u"收藏數")
add_time = models.DateTimeField(default=datetime.now)
class Meta:
verbose_name = u"教師"
verbose_name_plural = verbose_name
operation models.py
設計結構:
1. UserAsk - 使用者咨詢
2. CourseComments - 使用者評論
3. UserFavorite - 使用者收藏
4. UserMessage - 使用者消息
5. UserCourse - 使用者學習的課程
設計代碼如下:
#_*_ 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=, verbose_name=u"姓名")
mobile = models.CharField(max_length=, verbose_name=u"手機")
course_name = models.CharField(max_length=, 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=, 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=, verbose_name=u"資料ID")
fav_type = models.IntegerField(choices=((,u"課程"),(,u"課程機構"),(,u"講師")),default=, 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=, verbose_name=u"接收使用者")
message = models.CharField(max_length=, 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
資料庫生成以及apps目錄建立
打開manage.py task
[email protected] > makemigrations
bash -cl "/home/liang/.virtualenvs/mxonline/bin/python2.7 /home/liang/pycharm-2017.2.4/helpers/pycharm/django_manage.py makemigrations /home/liang/PycharmProjects/MxOnline"
Migrations for 'courses':
0001_initial.py:
- Create model Course
- Create model CourseResource
- Create model Lesson
- Create model Video
Migrations for 'operation':
0001_initial.py:
- Create model CourseComments
- Create model UserAsk
- Create model UserCourse
- Create model UserFavorite
- Create model UserMessage
Migrations for 'users':
0002_banner_emailverifyrecord.py:
- Create model Banner
- Create model EmailVerifyRecord
Migrations for 'organization':
0001_initial.py:
- Create model CityDict
- Create model CourseOrg
- Create model Teacher
Following files were affected
/home/liang/PycharmProjects/MxOnline/organization/migrations/0001_initial.py
/home/liang/PycharmProjects/MxOnline/courses/migrations/0001_initial.py
/home/liang/PycharmProjects/MxOnline/operation/migrations/0001_initial.py
/home/liang/PycharmProjects/MxOnline/users/migrations/0002_banner_emailverifyrecord.py
Process finished with exit code 0
此時每個app檔案夾下會生成migrations檔案夾
當app數量過多時,應該把他們單獨放入一個檔案夾便于管理
然後執行==右擊apps檔案夾 > Mark Directory as > Sources Root==,這樣,在根目錄下找不到的表可以在apps目錄下繼續尋找,但是這樣仍然不夠,在指令行下運作python manage.py runserver 時,仍然會報錯找不到users
[email protected]:~/PycharmProjects/MxOnline$ python manage.py runserver
Unhandled exception in thread started by <function wrapper at 0x7ff40c02cc80>
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/django/utils/autoreload.py", line , in wrapper
fn(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/core/management/commands/runserver.py", line , in inner_run
autoreload.raise_last_exception()
File "/usr/local/lib/python2.7/dist-packages/django/utils/autoreload.py", line , in raise_last_exception
six.reraise(*_exception)
File "/usr/local/lib/python2.7/dist-packages/django/utils/autoreload.py", line , in wrapper
fn(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/__init__.py", line , in setup
apps.populate(settings.INSTALLED_APPS)
File "/usr/local/lib/python2.7/dist-packages/django/apps/registry.py", line , in populate
app_config = AppConfig.create(entry)
File "/usr/local/lib/python2.7/dist-packages/django/apps/config.py", line , in create
module = import_module(entry)
File "/usr/lib/python2.7/importlib/__init__.py", line , in import_module
__import__(name)
ImportError: No module named users
此時要編輯MxOnline/settings.py檔案,将根目錄注冊到settings檔案中
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(,os.path.join(BASE_DIR,'apps'))
此時,用PyCharm Debug該項目,正常
停止運作,在指令行中運作該項目,正常
(mxonline) liang@l:~/PycharmProjects/MxOnline$ python manage.py runserver
Performing system checks...
System check identified no issues ( silenced).
November , - ::
Django version , using settings 'MxOnline.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.