跳转至

项目

项目需求

角色: 学校、学生、课程、讲师
要求:
     1> 创建北京、上海两所学校 --- 创建学校
     2> 创建linux、python、go 三门课程. linux/py在北京开,go在上海开 --- 创建课程,课程关联学校
     3> 管理员 创建学校,老师,课程 --- 创建学校、创建老师、创建课程
     4> 课程包含课程名称 (周期,价格等属性) --- 课程属性 
     5> 学校包含学校名称、地址等属性 --- 学校属性 
     6> 创建老师角色要关联学校
     7> 学生登录后,可以选这学校、选择课程、查看成绩. --- 选择学校,选择课程,查看成绩
     8> 老师登录后, 可以查看教授的课程, 选择要教授的课程, 查看课程下的学生, 修改学生成绩等.

分为三个视图:
◎ 管理员视图
        注册
        登录
        创建学校
        创建老师
        创建课程
◎ 老师视图
       登录
       选择课程
       查看课程
       查看学生
       修改学生成绩
◎ 学生视图
        注册
        登录
        选择学校
        选择课程
        查看成绩


项目工程目录

One_Piece@DCdeMacBook-Air CourseSelection % tree
.
├── conf
│   ├── __init__.py
│   └── settings.py
├── core
│   ├── __init__.py
│   ├── admin.py
│   ├── src.py
│   ├── student.py
│   └── teacher.py
├── db
│   ├── __init__.py
│   ├── db_handler.py
│   └── models.py
├── interface
│   ├── __init__.py
│   ├── admin_interface.py
│   ├── common_interface.py
│   ├── student_interface.py
│   └── teacher_interface.py
├── lib
│   ├── __init__.py
│   └── common.py
└── start.py

########################################################################
                                【日志】

【用户功能层】                    【接口层】              【数据处理层】
admin视图:                   admin_interface         models 类及方法
   注册登录                  teacher_interface       db_handler 保存、查询
   创建学校、老师..            student_interface       
teacher视图:                 common_interface        
   登录
   选择课程
   ...
student视图:
   登录、注册
   选择学校
   选择课程
   查看成绩
                               【common】
########################################################################

写代码

先写好用户功能层框架..
再完成一个个的功能,用到其它层的时候再到其它层进行完善..

# -- start.py
import os
import sys

from core import src

path = os.path.dirname(__file__)
sys.path.append(path)

if __name__ == '__main__':
    src.run()


# -- src.py
from core import admin, student, teacher

func_dic = {
    '1': admin.admin_view,
    '2': student.student_view,
    '3': teacher.teacher_view
}

def run():
    while True:
        print("""
        1.管理员视图
        2.学生视图
        3.老师视图
        """)
        choice = input("请输入数字选择视图 >>:").strip()
        if choice not in func_dic: continue
        func_dic[choice]()


# -- admin.py
def admin_register(): pass
def admin_login(): pass
def create_school(): pass
def create_teacher(): pass
def create_course(): pass

func_dic = {
    '1': admin_register,
    '2': admin_login,
    '3': create_school,
    '4': create_teacher,
    '5': create_course
}

def admin_view():
    while True:
        print("""
        1.注册
        2.登录
        3.创建学校
        4.创建老师
        5.创建课程
        """)
        choice = input("请输入数字选择功能 >>:").strip()
        if choice not in func_dic: continue
        func_dic[choice]()


# -- student.py
def student_register(): pass
def student_login(): pass
def choose_school(): pass
def choose_course(): pass
def check_score(): pass

func_dic = {
    '1': student_register,
    '2': student_login,
    '3': choose_school,
    '4': choose_course,
    '5': check_score
}

def student_view():
    while True:
        print("""
        1.注册
        2.登录
        3.选择学校
        4.选择课程
        5.查看成绩
        """)
        choice = input("请输入数字选择功能 >>:").strip()
        if choice not in func_dic: continue
        func_dic[choice]()


# -- teacher.py
def teacher_login(): pass
def choose_teach_course(): pass
def check_course(): pass
def check_student(): pass
def modify_score(): pass

func_dic = {
    '1': teacher_login,
    '2': choose_teach_course,
    '3': check_course,
    '4': check_student,
    '5': modify_score
}

def teacher_view():
    while True:
        print("""
        1.登录
        2.选择课程
        3.查看课程
        4.查看学生
        5.修改学生成绩
        """)
        choice = input("请输入数字选择功能 >>:").strip()
        if choice not in func_dic: continue
        func_dic[choice]()

最核心的代码

# -- models.py
from db import db_handler


class BaseClass:
    def save(self):
        # -- 将实例对象存储到pickle文件中"以实例化对象名字命名",并分门别类的存储到对应的文件夹下面"以类名命名"
        db_handler.save(self)

    @classmethod
    # -- 分析: 查询为什么要使用类方法?
    #    若用实例对象的绑定方法,需要先把这个实例对象生成出来后再查.
    #        可以这样做,但感觉生成对象去查对象..不是很perfect.
    #    若用静态方法,静态方法不会自动把类传过来.. 该查询需要用到类.
    def get_obj_by_name(cls, name):
        # -- 根据名字取出对应pikle文件中存储的实例对象
        #    name实际上是实例化对象的名字;cls.__name__.lower() 小写的类名
        return db_handler.select(name, cls.__name__.lower())

class Admin(BaseClass):
    def __init__(self, name, pwd):
        self.name = name
        self.pwd = pwd
        self.save()


# -- db_handler.py
import os
import pickle

from conf import settings


def save(obj):
    # -- obj是我们要保存的实例对象
    #    obj.__class__ >>> 实例调用__class__属性时会指向该实例对应的类
    #    obj.__class__.__name__ >>> 获取类名
    path_dir = os.path.join(settings.BASE_DB, obj.__class__.__name__.lower())
    if not os.path.isdir(path_dir):  # os.path.exists 也可以
        os.mkdir(path_dir)
    path_obj = os.path.join(path_dir, obj.name)
    # -- 之所以用pickle,是因为pickle可以直接保存对象..
    #    用json的话需要构建json格式,相对复杂一点.
    with open(path_obj, 'wb') as f:
        pickle.dump(obj, f)

def select(obj_name, dir_name):
    # -- 根据obj _name和dir_type将某一个文件夹下的pickle文件取出来
    path_dir = os.path.join(settings.BASE_DB, dir_name)
    # -- 可能会出现管理员先查询,再创建的情况.
    if not os.path.isdir(path_dir):
        os.mkdir(path_dir)
    path_obj = os.path.join(path_dir, obj_name)
    if os.path.exists(path_obj):
        with open(path_obj, 'rb') as f:
            return pickle.load(f)
    else:
        return False

简单分析

以Admin管理员视图功能的实现为例

"""
★ ---用户层/前端
"""
管理员的注册功能,需要用户输入name和pwd字段.
程序接收到这两个字段后,进行健壮性的判断,就开始调用接口..等待结果的返回,啥也不用管啦!!

创建老师学校课程就是创建对应的obj保存起来..

"""
★ ---接口层
"""
需要先检查注册的管理员是否已经存在,需要调用数据处理层.
存在返回 False,"已经存在"
不存在 创建管理员对象 -- 通过数据处理层的models.py实现

"""
★ ---数据处理层
"""
分为了models.py和db_handler.py

models.py里是一堆类及方法
    Base基类 -- 查询和保存
    学校老师管理员学生课程 四个类都会继承Base基类.
        在它们初始化的时候,都会调用save()方法;
        在它们中的属性发生改变时候,也需要调用save()方法重新保存.
查询和保存在 db_handler.py中实现!
    save() 打开文件,往里面写
    select() 打开文件,取obj返回