├── .gitignore ├── Course ├── CourseSerializer.py ├── __init__.py ├── admin.py ├── apps.py ├── migrations │ └── __init__.py ├── models.py ├── tests.py ├── urls.py └── views.py ├── LICENSE ├── README-images ├── v1.0 │ ├── 作业管理界面.png │ ├── 后台管理界面.png │ └── 获取接口简单使用说明.png ├── 作业管理界面.png ├── 后台管理界面.png ├── 获取接口简单使用说明.png └── 课程管理界面.png ├── README.md ├── SchoolAssignmentListManage ├── __init__.py ├── admin.py ├── apps.py ├── diy_widgets.py ├── migrations │ └── __init__.py ├── models.py ├── templates │ ├── add.png │ └── image_multi_upload.html ├── tests.py ├── urls.py └── views.py ├── SchoolAssignmentManageSystem ├── __init__.py ├── settings.py ├── urls.py └── wsgi.py ├── manage.py └── requirements.txt /.gitignore: -------------------------------------------------------------------------------- 1 | # using settings 2 | .gitignore 3 | tree.py 4 | tree.txt 5 | .vscode/ 6 | .idea/ 7 | SchoolAssignmentListManage/admin副本.py 8 | 9 | # 忽略所有 migrations 目录下的 .py 文件 10 | **/migrations/*.py 11 | 12 | # 但不忽略 __init__.py 13 | !**/migrations/__init__.py 14 | 15 | # default settings 16 | 17 | # Byte-compiled / optimized / DLL files 18 | __pycache__/ 19 | *.py[cod] 20 | *$py.class 21 | 22 | # C extensions 23 | *.so 24 | 25 | # Distribution / packaging 26 | .Python 27 | build/ 28 | develop-eggs/ 29 | dist/ 30 | downloads/ 31 | eggs/ 32 | .eggs/ 33 | lib/ 34 | lib64/ 35 | parts/ 36 | sdist/ 37 | var/ 38 | wheels/ 39 | pip-wheel-metadata/ 40 | share/python-wheels/ 41 | *.egg-info/ 42 | .installed.cfg 43 | *.egg 44 | MANIFEST 45 | 46 | # PyInstaller 47 | # Usually these files are written by a python script from a template 48 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 49 | *.manifest 50 | *.spec 51 | 52 | # Installer logs 53 | pip-log.txt 54 | pip-delete-this-directory.txt 55 | 56 | # Unit test / coverage reports 57 | htmlcov/ 58 | .tox/ 59 | .nox/ 60 | .coverage 61 | .coverage.* 62 | .cache 63 | nosetests.xml 64 | coverage.xml 65 | *.cover 66 | *.py,cover 67 | .hypothesis/ 68 | .pytest_cache/ 69 | 70 | # Translations 71 | *.mo 72 | *.pot 73 | 74 | # Django stuff: 75 | *.log 76 | local_settings.py 77 | db.sqlite3 78 | db.sqlite3-journal 79 | 80 | # Flask stuff: 81 | instance/ 82 | .webassets-cache 83 | 84 | # Scrapy stuff: 85 | .scrapy 86 | 87 | # Sphinx documentation 88 | docs/_build/ 89 | 90 | # PyBuilder 91 | target/ 92 | 93 | # Jupyter Notebook 94 | .ipynb_checkpoints 95 | 96 | # IPython 97 | profile_default/ 98 | ipython_config.py 99 | 100 | # pyenv 101 | .python-version 102 | 103 | # pipenv 104 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 105 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 106 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 107 | # install all needed dependencies. 108 | #Pipfile.lock 109 | 110 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 111 | __pypackages__/ 112 | 113 | # Celery stuff 114 | celerybeat-schedule 115 | celerybeat.pid 116 | 117 | # SageMath parsed files 118 | *.sage.py 119 | 120 | # Environments 121 | .env 122 | .venv 123 | env/ 124 | venv/ 125 | ENV/ 126 | env.bak/ 127 | venv.bak/ 128 | 129 | # Spyder project settings 130 | .spyderproject 131 | .spyproject 132 | 133 | # Rope project settings 134 | .ropeproject 135 | 136 | # mkdocs documentation 137 | /site 138 | 139 | # mypy 140 | .mypy_cache/ 141 | .dmypy.json 142 | dmypy.json 143 | 144 | # Pyre type checker 145 | .pyre/ 146 | -------------------------------------------------------------------------------- /Course/CourseSerializer.py: -------------------------------------------------------------------------------- 1 | # !/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | # @Time : 2020/10/3 16:32 4 | # @Author: 韩家旭 5 | # @File : CourseSerializer.py 6 | 7 | from rest_framework import serializers 8 | from rest_framework.utils.field_mapping import get_nested_relation_kwargs 9 | from datetime import time 10 | from .models import ClassSchedule 11 | 12 | 13 | class CourseSerializer(serializers.ModelSerializer): 14 | 15 | def build_nested_field(self, field_name, relation_info, nested_depth): 16 | """ 17 | Create nested fields for forward and reverse relationships. 18 | """ 19 | 20 | class NestedSerializer(serializers.ModelSerializer): 21 | class Meta: 22 | model = relation_info.related_model 23 | depth = nested_depth - 1 24 | fields = '__all__' 25 | extra_kwargs = self.get_extra_kwargs() 26 | 27 | field_class = NestedSerializer 28 | field_kwargs = get_nested_relation_kwargs(relation_info) 29 | 30 | return field_class, field_kwargs 31 | 32 | @staticmethod 33 | def get_time_interval(obj): 34 | start_time = obj.lesson.start_time 35 | end_time = obj.lesson.end_time 36 | midday_time = time(12, 0, 0) 37 | if start_time.__lt__(midday_time): 38 | return '上午' 39 | else: 40 | return '下午' 41 | 42 | time_interval = serializers.SerializerMethodField() 43 | 44 | class Meta: 45 | model = ClassSchedule 46 | fields = '__all__' 47 | depth = 2 48 | extra_kwargs = { 49 | 'start_time': {'format': '%H:%M'}, 50 | 'end_time': {'format': '%H:%M'} 51 | } 52 | -------------------------------------------------------------------------------- /Course/__init__.py: -------------------------------------------------------------------------------- 1 | default_app_config = 'Course.apps.CourseConfig' 2 | -------------------------------------------------------------------------------- /Course/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | 5 | from datetime import datetime, timedelta 6 | 7 | from .models import * 8 | 9 | from import_export import resources 10 | 11 | 12 | @admin.register(TermInfo) 13 | class TermInfoAdmin(admin.ModelAdmin): 14 | list_display = [ 15 | 'pk', 'term_name', 16 | 'start_date', 'end_date', 17 | 'week_counts' 18 | ] 19 | 20 | search_fields = ('term_name', 'start_date', 'end_date') 21 | 22 | # list_filter = ('course_name', EndTimeListFilter, 23 | # TimeOutListFilter, 'end_time') 24 | list_filter = ('term_name', ) 25 | 26 | list_display_links = ('pk', 'term_name') 27 | 28 | list_editable = ('start_date', 'end_date', 'week_counts') 29 | 30 | # fieldsets = [(None, {'fields': ['term_name', 'start_time', 'end_time', 'week_counts', 'current_week']}), 31 | # (u'其他信息', { 32 | # 'fields': ['additionalInfo', 'upload_file']})] 33 | 34 | ordering = ('-start_date', ) 35 | 36 | 37 | @admin.register(Teacher) 38 | class TeacherAdmin(admin.ModelAdmin): 39 | list_display = [ 40 | 'pk', 'name', 41 | 'gender' 42 | ] 43 | 44 | search_fields = ('name',) 45 | 46 | list_filter = ('gender',) 47 | 48 | list_display_links = ('pk', 'name') 49 | 50 | list_editable = ('gender',) 51 | 52 | ordering = ('pk',) 53 | 54 | 55 | @admin.register(Course) 56 | class CourseAdmin(admin.ModelAdmin): 57 | list_display = [ 58 | 'pk', 'course_name', 59 | 'teacher', 'assessment_method' 60 | ] 61 | 62 | search_fields = ('course_name', 'teacher__name') 63 | 64 | list_filter = ('teacher', 'assessment_method') 65 | 66 | list_display_links = ('pk', 'course_name') 67 | 68 | list_editable = ('teacher', 'assessment_method') 69 | 70 | ordering = ('pk',) 71 | 72 | 73 | @admin.register(LessonSchedule) 74 | class LessonScheduleAdmin(admin.ModelAdmin): 75 | list_display = [ 76 | 'pk', 'title', 77 | 'start_time', 'end_time' 78 | ] 79 | 80 | search_fields = ('title',) 81 | 82 | list_display_links = ('pk', 'title') 83 | 84 | list_editable = ('start_time', 'end_time') 85 | 86 | ordering = ('pk', ) 87 | 88 | 89 | @admin.register(ClassSchedule) 90 | class ClassScheduleAdmin(admin.ModelAdmin): 91 | list_display = [ 92 | 'pk', 'course', 93 | 'week_day', 'classroom', 94 | 'weeks', 'lesson', 95 | 'is_suspend' 96 | ] 97 | 98 | search_fields = ('course__course_name', 'classroom') 99 | 100 | list_filter = ('course', 'week_day', 'classroom', 'lesson', 'is_suspend') 101 | 102 | list_display_links = ('pk', 'course') 103 | 104 | list_editable = ('weeks', 'is_suspend',) 105 | 106 | # ordering = ('-start_date', ) 107 | ordering = ('pk',) 108 | 109 | 110 | admin.site.site_title = '教学管理后台' 111 | admin.site.site_header = '教学管理后台' 112 | 113 | -------------------------------------------------------------------------------- /Course/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class CourseConfig(AppConfig): 5 | name = 'Course' 6 | verbose_name = "教学信息管理" 7 | -------------------------------------------------------------------------------- /Course/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HanZephyr/SchoolAssignmentManageSystem/d3b1d44e18a55fc45dcdc4fd0071a4ac0d0d4c07/Course/migrations/__init__.py -------------------------------------------------------------------------------- /Course/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | # Create your models here. 4 | # from multiselectfield import MultiSelectField 5 | 6 | 7 | class ListField(models.CharField): 8 | # 9 | # def __init__(self, *args, **kwargs): 10 | # super().__init__(*args, **kwargs) 11 | 12 | def get_db_prep_value(self, value, connection=None, prepared=False): 13 | if isinstance(value, str): 14 | return value 15 | elif isinstance(value, list): 16 | return ",".join(value) 17 | 18 | def to_python(self, value): 19 | print('*' * 50) 20 | print(value) 21 | # if value is not None: 22 | # return value if isinstance(value, list) else value.split(',') 23 | # return [] 24 | return value 25 | 26 | # def get_prep_lookup(self, lookup_type, value): 27 | # """限制查询方式""" 28 | # print(value) 29 | # if lookup_type == 'exact': 30 | # return value 31 | # elif lookup_type == 'in': 32 | # print([self.get_prep_value(v) for v in value]) 33 | # return [self.get_prep_value(v) for v in value] 34 | # else: 35 | # return TypeError('lookup type %r not supported' % lookup_type) 36 | 37 | 38 | class TermInfo(models.Model): 39 | term_name = models.CharField(max_length=50, verbose_name='学期名称') 40 | start_date = models.DateField(verbose_name='学期开始日期') 41 | end_date = models.DateField(verbose_name='学期结束日期') 42 | week_counts = models.IntegerField(verbose_name='学期总周数', default=20) 43 | # current_week = models.IntegerField(verbose_name='当前周数', default=1) 44 | 45 | class Meta: 46 | db_table = 'TermInfo' 47 | verbose_name = '学期' 48 | verbose_name_plural = "学期管理" 49 | 50 | def __str__(self): 51 | return self.term_name 52 | 53 | 54 | class Teacher(models.Model): 55 | name = models.CharField(max_length=25, verbose_name='姓名') 56 | gender_choices = ( 57 | (1, '男'), 58 | (2, '女') 59 | ) 60 | gender = models.IntegerField(choices=gender_choices, blank=True, null=True, verbose_name='性别') 61 | 62 | class Meta: 63 | db_table = 'Teacher' 64 | verbose_name = '教师' 65 | verbose_name_plural = "教师管理" 66 | 67 | def __str__(self): 68 | return self.name 69 | 70 | 71 | class Course(models.Model): 72 | # 归属学期 73 | # term = models.ForeignKey(TermInfo, on_delete=models.SET_NULL, blank=True, null=True) 74 | # 科目名 75 | course_name = models.CharField(max_length=50, verbose_name='课程名称') 76 | teacher = models.ForeignKey(Teacher, on_delete=models.CASCADE, verbose_name='教师姓名', default=None) 77 | # 考核方式 78 | assessment_method_choices = ( 79 | ('考试', '考试'), 80 | ('考查', '考查') 81 | ) 82 | assessment_method = models.CharField(max_length=10, choices=assessment_method_choices, verbose_name='考核方式') 83 | 84 | class Meta: 85 | db_table = 'Course' 86 | verbose_name = '课程' 87 | verbose_name_plural = "课程名称管理" 88 | 89 | def __str__(self): 90 | return self.course_name 91 | 92 | 93 | class LessonSchedule(models.Model): 94 | title = models.CharField(max_length=20, verbose_name='名称') 95 | start_time = models.TimeField(verbose_name='上课时间') 96 | end_time = models.TimeField(verbose_name='下课时间') 97 | 98 | class Meta: 99 | db_table = 'LessonSchedule' 100 | verbose_name = '作息时间表' 101 | verbose_name_plural = "作息时间表管理" 102 | 103 | def __str__(self): 104 | return self.title 105 | 106 | 107 | class ClassSchedule(models.Model): 108 | # 当课程删除时,自动删除 109 | course = models.ForeignKey(Course, on_delete=models.CASCADE, verbose_name='课程名称') 110 | # 星期几 111 | week_day_choices = ( 112 | (1, '星期一'), 113 | (2, '星期二'), 114 | (3, '星期三'), 115 | (4, '星期四'), 116 | (5, '星期五'), 117 | (6, '星期六'), 118 | (7, '星期日') 119 | ) 120 | week_day = models.IntegerField(choices=week_day_choices, verbose_name='星期几') 121 | # 教室 122 | classroom = models.CharField(max_length=50, verbose_name='教室') 123 | # 周次 124 | weeks_choices = tuple([(i, i) for i in range(1, 21)]) 125 | # weeks = MultiSelectField(choices=weeks_choices, max_length=256, verbose_name='周次') 126 | weeks = ListField(max_length=256, verbose_name='周次') 127 | # 节次 128 | lesson = models.ForeignKey(LessonSchedule, on_delete=models.CASCADE, verbose_name='节次') 129 | # 是否停课 130 | is_suspend = models.BooleanField(default=False, verbose_name='是否停课') 131 | 132 | class Meta: 133 | db_table = 'ClassSchedule' 134 | verbose_name = '课程表' 135 | verbose_name_plural = "课程表管理" 136 | 137 | def __str__(self): 138 | return ' | '.join([str(self.course), str(self.get_week_day_display()), str(self.lesson)]) 139 | 140 | 141 | 142 | 143 | 144 | -------------------------------------------------------------------------------- /Course/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /Course/urls.py: -------------------------------------------------------------------------------- 1 | # !/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | # @Time : 2020/4/13 11:57 4 | # @Author: 韩家旭 5 | # @File : urls.py 6 | 7 | from django.conf.urls import url 8 | from django.urls import path, re_path 9 | 10 | from . import views 11 | 12 | app_name = '[Course]' 13 | 14 | urlpatterns = [ 15 | # path('get_assignments/', views.get_assignments) 16 | url(r'^course/$', 17 | views.CourseSchedule.as_view({ 18 | 'get': 'get_day_course', 19 | }), name='get_day_course'), 20 | ] 21 | -------------------------------------------------------------------------------- /Course/views.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime, timedelta 2 | 3 | from django.shortcuts import render 4 | 5 | # Create your views here. 6 | from django.http.response import JsonResponse 7 | from rest_framework.viewsets import ModelViewSet 8 | from django.db.models import Q 9 | from .models import * 10 | from .CourseSerializer import CourseSerializer 11 | 12 | 13 | class CourseSchedule(ModelViewSet): 14 | def get_day_course(self, request, *args, **kwargs): 15 | params = request.query_params 16 | if 'week_day' in params: 17 | week_day = params['week_day'] 18 | else: 19 | week_day = datetime.now().weekday() + 1 20 | if 'week_count' in params: 21 | week_count = params['week_count'] 22 | else: 23 | this_week_start = datetime.now() - timedelta(days=datetime.now().weekday()) 24 | start_study_day = datetime.strptime( 25 | str(TermInfo.objects.all().order_by('-start_date').first().start_date), 26 | '%Y-%m-%d' 27 | ) 28 | week_count = int((this_week_start - start_study_day).days / 7 + 1) 29 | ClassSchedule_QuerySet = ClassSchedule.objects.filter( 30 | Q(week_day=week_day) & 31 | Q(is_suspend=False) 32 | ).order_by('lesson__start_time') 33 | ClassSchedule_QuerySet_Serializer = CourseSerializer(instance=ClassSchedule_QuerySet, 34 | many=True, 35 | context={'request': request}) 36 | 37 | ClassSchedule_data = ClassSchedule_QuerySet_Serializer.data 38 | print(ClassSchedule_data) 39 | class_schedule_list = list(filter(lambda x: str(week_count) in x['weeks'].split(','), ClassSchedule_data)) 40 | 41 | res_json = { 42 | 'code': 0, 43 | 'msg': '成功', 44 | 'week_day': int(week_day), 45 | 'week_count': int(week_count), 46 | 'data': class_schedule_list 47 | } 48 | return JsonResponse(res_json, json_dumps_params={'ensure_ascii': False}) 49 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 冬酒暖阳 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README-images/v1.0/作业管理界面.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HanZephyr/SchoolAssignmentManageSystem/d3b1d44e18a55fc45dcdc4fd0071a4ac0d0d4c07/README-images/v1.0/作业管理界面.png -------------------------------------------------------------------------------- /README-images/v1.0/后台管理界面.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HanZephyr/SchoolAssignmentManageSystem/d3b1d44e18a55fc45dcdc4fd0071a4ac0d0d4c07/README-images/v1.0/后台管理界面.png -------------------------------------------------------------------------------- /README-images/v1.0/获取接口简单使用说明.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HanZephyr/SchoolAssignmentManageSystem/d3b1d44e18a55fc45dcdc4fd0071a4ac0d0d4c07/README-images/v1.0/获取接口简单使用说明.png -------------------------------------------------------------------------------- /README-images/作业管理界面.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HanZephyr/SchoolAssignmentManageSystem/d3b1d44e18a55fc45dcdc4fd0071a4ac0d0d4c07/README-images/作业管理界面.png -------------------------------------------------------------------------------- /README-images/后台管理界面.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HanZephyr/SchoolAssignmentManageSystem/d3b1d44e18a55fc45dcdc4fd0071a4ac0d0d4c07/README-images/后台管理界面.png -------------------------------------------------------------------------------- /README-images/获取接口简单使用说明.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HanZephyr/SchoolAssignmentManageSystem/d3b1d44e18a55fc45dcdc4fd0071a4ac0d0d4c07/README-images/获取接口简单使用说明.png -------------------------------------------------------------------------------- /README-images/课程管理界面.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HanZephyr/SchoolAssignmentManageSystem/d3b1d44e18a55fc45dcdc4fd0071a4ac0d0d4c07/README-images/课程管理界面.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 作业管理系统 2 | 3 | [](http://www.lifepoem.cn/) [](https://www.python.org/) [](https://github.com/allwaysLove/ChaoXing-Automatic-watch-Course/releases) [](https://github.com/allwaysLove/ChaoXing-Automatic-watch-Course/blob/master/LICENSE) 4 | 5 | 6 | 7 | ## :bulb: 简介 8 | 9 | **[SchoolAssignmentManageSystem](https://github.com/allwaysLove/SchoolAssignmentManageSystem)** 一款基于 **Python3 与 Django WEB框架** 的作业管理系统,提供作业管理及查询服务 10 | 11 | 12 | 13 | ## :sparkling_heart: 作者 14 | 15 | | Author | E-mail | Blog | 16 | | ------------------------------------------ | --------------------------------------------- | ------------------------------------------------ | 17 | | [冬酒暖阳](https://github.com/allwaysLove) | [1067764354@qq.com](mailto:1067764354@qq.com) | [博客:www.lifepoem.cn](https://www.lifepoem.cn) | 18 | 19 | ## :postal_horn: 界面展示 20 | 21 | 1. 后台管理界面 22 | 23 |  24 | 25 | 2. 作业管理界面 26 | 27 |  28 | 29 | 3. 课程表管理系统 30 | 31 |  32 | 33 | 4. 获取接口简单使用说明 34 | 35 |  36 | 37 | ## :hammer: 安装 38 | 39 | 1. 通过源代码安装 40 | 41 | ```shell 42 | git clone https://github.com/allwaysLove/SchoolAssignmentManageSystem.git 43 | python -m pip install -r requirements.txt 44 | ``` 45 | 46 | 47 | 48 | 49 | ## :blue_book: 使用 50 | 51 | 1. 使用命令行 cd 到项目根目录 52 | 53 | 2. 执行以下命令 54 | 55 | ```shell 56 | # 创建超级用户(管理员) 57 | python manage.py createsuperuser 58 | # 依据模型迁移构建数据库表 59 | python manage.py makemigrations 60 | python manage.py migrate 61 | ``` 62 | 63 | 3. 使用 runserver 命令开启服务器 64 | 65 | ```shell 66 | python manage.py runserver 0.0.0.0:8000 67 | ``` 68 | 69 | 4. 随后便可在本地浏览器访问 http://localhost:8000/admin 看到作业管理系统,登陆用户名及密码即为刚才创建的超级用户的用户名与密码 70 | 71 | 72 | 73 | ## :memo: 目录结构及文件注释 74 | 75 | ``` 76 | SchoolAssignmentManageSystem/ 77 | ├────.gitignore 78 | ├────LICENSE 79 | ├────manage.py 80 | ├────README.md 81 | ├────requirements.txt 82 | ├────Course/ 83 | │ ├────__init__.py 84 | │ ├────migrations/ 85 | │ ├────admin.py 86 | │ ├────apps.py 87 | │ ├────CourseSerializer.py 88 | │ ├────models.py 89 | │ ├────tests.py 90 | │ ├────urls.py 91 | │ └────views.py 92 | ├────SchoolAssignmentListManage/ 93 | │ ├────__init__.py 94 | │ ├────admin.py 95 | │ ├────apps.py 96 | │ ├────diy_widgets.py 97 | │ ├────models.py 98 | │ ├────templates/ 99 | │ │ ├────add.png 100 | │ │ └────image_multi_upload.html 101 | │ ├────tests.py 102 | │ ├────urls.py 103 | │ └────views.py 104 | └────SchoolAssignmentManageSystem/ 105 | ├────__init__.py 106 | ├────settings.py 107 | ├────urls.py 108 | └────wsgi.py 109 | ``` 110 | 111 | >| 文件名 | 注释 | 112 | >| --------------- | ------------------- | 113 | >| .gitignore | git 忽略文件 | 114 | >| LICENSE | MIT许可证 | 115 | >| manage.py | Django 项目命令工具 | 116 | >| README.md | 说明文档 | 117 | >| requirments.txt | 项目代码主要依赖库 | 118 | >| models.py | 数据库模型 | 119 | >| urls.py | 应用路由配置 | 120 | >| settings.py | Django项目配置 | 121 | >| urls.py | 项目路由配置 | 122 | 123 | 124 | 125 | 126 | 127 | ## :bookmark_tabs:版本更新日志 128 | 129 | > ### [1.0.0] - 2020-03-26 130 | > #### 项目1.0版本 131 | > * 课程名称编辑 132 | > * 作业管理(增删改查) 133 | > * 通过接口获取 JSON 格式作业数据 134 | > * 美观的后台管理界面 135 | 136 | > ### [2.0.0] - 2020-10-03 137 | > #### 项目2.0版本 138 | > * 扩展了作业管理功能 139 | > * 课程管理 140 | > * 通过接口获取 JSON 格式课程数据 141 | > * 作息时间表管理 142 | > * 学期管理 143 | > * 教师管理 144 | > * 课程名称管理 145 | 146 | 147 | 148 | ## :clipboard: To-Do List 149 | 150 | 151 | 152 | 153 | 154 | ## :bookmark_tabs: License 155 | 156 | [MIT © 2020 冬酒暖阳](https://github.com/allwaysLove/SchoolAssignmentManageSystem/blob/master/LICENSE) 157 | 158 | -------------------------------------------------------------------------------- /SchoolAssignmentListManage/__init__.py: -------------------------------------------------------------------------------- 1 | default_app_config = 'SchoolAssignmentListManage.apps.SchoolassignmentlistmanageConfig' 2 | -------------------------------------------------------------------------------- /SchoolAssignmentListManage/admin.py: -------------------------------------------------------------------------------- 1 | # -*- coding: UTF-8 -*- 2 | from django.contrib import admin 3 | from datetime import datetime, timedelta 4 | 5 | # Register your models here. 6 | 7 | from SchoolAssignmentListManage.models import * 8 | 9 | from import_export import resources 10 | 11 | # 12 | # @admin.register(ScheduleName) 13 | # class ScheduleNameAdmin(admin.ModelAdmin): 14 | # # pk:索引 15 | # # 属性 list_display 表示要显示哪些属性 16 | # list_display = ['pk', 'course_name'] 17 | # list_display_links = ('pk', 'course_name') 18 | # 19 | # ordering = ('pk',) 20 | 21 | 22 | class EndTimeListFilter(admin.SimpleListFilter): 23 | title = u'最近截止' 24 | parameter_name = 'EndTime' 25 | 26 | def lookups(self, request, model_admin): 27 | return ( 28 | ('0', u'最近7天'), 29 | ('1', u'最近10天'), 30 | ('2', u'最近15天'), 31 | ('3', u'最近30天'), 32 | ) 33 | 34 | def queryset(self, request, queryset): 35 | # 当前日期格式 36 | cur_date = datetime.now().date() 37 | 38 | if self.value() == '0': 39 | # 前一天日期 40 | day = cur_date + timedelta(days=7) 41 | return queryset.filter(end_time__lte=day) 42 | elif self.value() == '1': 43 | day = cur_date + timedelta(days=10) 44 | return queryset.filter(end_time__lte=day) 45 | elif self.value() == '2': 46 | day = cur_date + timedelta(days=15) 47 | return queryset.filter(end_time__lte=day) 48 | elif self.value() == '3': 49 | day = cur_date + timedelta(days=30) 50 | return queryset.filter(end_time__lte=day) 51 | 52 | 53 | class TimeOutListFilter(admin.SimpleListFilter): 54 | title = u'是否超时(默认 未截止)' 55 | parameter_name = 'TimeOut' 56 | 57 | def lookups(self, request, model_admin): 58 | return ( 59 | ('0', u'未截止'), 60 | ('1', u'已截止'), 61 | ('2', u'所有'), 62 | ) 63 | 64 | def queryset(self, request, queryset): 65 | # 当前日期格式 66 | cur_date = datetime.now() 67 | seven_days_ago = cur_date - timedelta(days=7) 68 | 69 | print('self.value():', self.value()) 70 | 71 | if self.value() == '0' or not self.value(): 72 | # 前一天日期 73 | return queryset.exclude(end_time__isnull=False, 74 | end_time__lt=cur_date).exclude(end_time__isnull=True, start_time__lte=seven_days_ago) 75 | elif self.value() == '1': 76 | return queryset.exclude(end_time__isnull=False, 77 | end_time__gte=cur_date).exclude(end_time__isnull=True, start_time__gt=seven_days_ago) 78 | elif self.value() == '2': 79 | day = cur_date + timedelta(days=15) 80 | return queryset 81 | 82 | 83 | class AssignmentInfoResource(resources.ModelResource): 84 | class Meta: 85 | model = AssignmentInfo 86 | 87 | 88 | @admin.register(AssignmentInfo) 89 | class AssignmentInfoAdmin(admin.ModelAdmin): 90 | list_display = ['pk', 'course_name', 91 | 'assignmentInfo', 'start_time', 'end_time'] 92 | 93 | search_fields = ('assignmentInfo',) 94 | 95 | list_filter = ('course_name', EndTimeListFilter, 96 | TimeOutListFilter, 'end_time') 97 | 98 | list_display_links = ('pk', 'course_name') 99 | 100 | list_editable = ('assignmentInfo', 'start_time', 'end_time') 101 | 102 | fieldsets = [(None, {'fields': ['course_name', 'assignmentInfo', 'start_time', 'end_time']}), 103 | (u'其他信息', { 104 | 'fields': ['additionalInfo', 'file', 'image']})] 105 | 106 | ordering = ('end_time', '-start_time') 107 | 108 | 109 | admin.site.site_title = '教学管理后台' 110 | admin.site.site_header = '教学管理后台' 111 | -------------------------------------------------------------------------------- /SchoolAssignmentListManage/apps.py: -------------------------------------------------------------------------------- 1 | # -*- coding: UTF-8 -*- 2 | from django.apps import AppConfig 3 | 4 | 5 | class SchoolassignmentlistmanageConfig(AppConfig): 6 | name = 'SchoolAssignmentListManage' 7 | verbose_name = "作业信息管理" 8 | 9 | -------------------------------------------------------------------------------- /SchoolAssignmentListManage/diy_widgets.py: -------------------------------------------------------------------------------- 1 | # !/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | # @Time : 2020/4/12 20:51 4 | # @Author: 韩家旭 5 | # @File : diy_widgets.py.py 6 | 7 | from django.forms import ClearableFileInput, ModelForm, forms 8 | from django.template import loader 9 | from django.utils.safestring import mark_safe 10 | from django.db import models 11 | 12 | 13 | class ImageInput(ClearableFileInput): 14 | template_name = 'image_multi_upload.html' 15 | 16 | def render(self, name, value, attrs=None, renderer=None): 17 | context = self.get_context(name, value, attrs) 18 | template = loader.get_template(self.template_name).render(context) 19 | return mark_safe(template) 20 | 21 | 22 | class UploadModel(models.Model): 23 | images = models.FileField('图片', upload_to="static/Assignment/UploadImg") 24 | 25 | 26 | class UploadForm(ModelForm): 27 | images = forms.FileField(label="图片", widget=ImageInput, help_text="按住ctrl多选,最多4张", required=False) 28 | 29 | class Meta: 30 | model = UploadModel 31 | fields = ['images'] 32 | 33 | 34 | -------------------------------------------------------------------------------- /SchoolAssignmentListManage/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HanZephyr/SchoolAssignmentManageSystem/d3b1d44e18a55fc45dcdc4fd0071a4ac0d0d4c07/SchoolAssignmentListManage/migrations/__init__.py -------------------------------------------------------------------------------- /SchoolAssignmentListManage/models.py: -------------------------------------------------------------------------------- 1 | # -*- coding: UTF-8 -*- 2 | from datetime import datetime 3 | 4 | from django.contrib.auth.models import User 5 | from django.db import models 6 | 7 | # Create your models here. 8 | 9 | # 课程名 10 | from django.utils import timezone 11 | 12 | from SchoolAssignmentListManage.diy_widgets import ImageInput, UploadModel 13 | from Course.models import Course 14 | 15 | 16 | class ScheduleName(models.Model): 17 | # 科目名 18 | # schedule_name = models.CharField(max_length=50, choices=schedule_name_choice) 19 | schedule_name = models.CharField(max_length=50, verbose_name='课程名称', unique=True) 20 | 21 | class Meta: 22 | db_table = 'schedule_name' 23 | verbose_name = '课程' 24 | verbose_name_plural = "课程管理" 25 | 26 | def __str__(self): 27 | return self.schedule_name 28 | 29 | 30 | class AssignmentInfo(models.Model): 31 | 32 | # 课程名 33 | course_name = models.ForeignKey(Course, on_delete=models.CASCADE, verbose_name='课程名称') 34 | 35 | # 作业信息 36 | assignmentInfo = models.CharField(verbose_name='作业内容', max_length=500) 37 | 38 | # 开始时间 39 | start_time = models.DateTimeField(verbose_name='开始时间', auto_now=False, default=timezone.now) 40 | # 结束时间 41 | end_time = models.DateTimeField(verbose_name='结束时间', auto_now=False, blank=True, null=True) 42 | 43 | # 补充信息 44 | additionalInfo = models.TextField(verbose_name='补充信息', blank=True, null=True, default=None) 45 | 46 | # 是否需要上传文件 47 | # is_need_upload_file = models.BooleanField(verbose_name='是否需要上传文件', default=False) 48 | 49 | # 文件 50 | file = models.FileField(verbose_name='文件', upload_to='file/', blank=True, null=True, default=None) 51 | 52 | # 图片 53 | image = models.ImageField(verbose_name='图片', upload_to='image/', blank=True, null=True, default=None) 54 | 55 | # images = forms.FileField(label="图片", widget=ImageInput, help_text="按住ctrl多选,最多4张", required=False) 56 | 57 | class Meta: 58 | # model = UploadModel 59 | verbose_name = '作业' 60 | verbose_name_plural = "作业管理" 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /SchoolAssignmentListManage/templates/add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HanZephyr/SchoolAssignmentManageSystem/d3b1d44e18a55fc45dcdc4fd0071a4ac0d0d4c07/SchoolAssignmentListManage/templates/add.png -------------------------------------------------------------------------------- /SchoolAssignmentListManage/templates/image_multi_upload.html: -------------------------------------------------------------------------------- 1 | {% load static %} 2 |
9 | -------------------------------------------------------------------------------- /SchoolAssignmentListManage/tests.py: -------------------------------------------------------------------------------- 1 | # -*- coding: UTF-8 -*- 2 | from django.test import TestCase 3 | 4 | # Create your tests here. 5 | -------------------------------------------------------------------------------- /SchoolAssignmentListManage/urls.py: -------------------------------------------------------------------------------- 1 | # !/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | # @Time : 2020/4/13 11:57 4 | # @Author: 韩家旭 5 | # @File : urls.py 6 | 7 | from django.conf.urls import url 8 | from django.urls import path, re_path 9 | 10 | from . import views 11 | 12 | app_name = '[SchoolAssignmentListManage]' 13 | 14 | urlpatterns = [ 15 | path('get_assignments/', views.get_assignments) 16 | ] 17 | -------------------------------------------------------------------------------- /SchoolAssignmentListManage/views.py: -------------------------------------------------------------------------------- 1 | # -*- coding: UTF-8 -*- 2 | 3 | 4 | from django.shortcuts import render 5 | 6 | # Create your views here. 7 | from django.http import HttpResponse, HttpResponseNotFound, Http404 8 | from django.db.models import Q 9 | from django.db.models.query import QuerySet 10 | from rest_framework.decorators import api_view 11 | from datetime import datetime, timedelta 12 | from json import dumps 13 | from .models import * 14 | from Course.models import Course 15 | 16 | 17 | # def get_assignment(request, assignment_type, days=None): 18 | 19 | @api_view(('GET',)) 20 | def get_assignments(request): 21 | """获取每周作业 22 | :param request: 请求 23 | # :param assignment_type: 获取作业类型(info:使用说明,week:本周未超时作业,all_effective:所有未超时,today:当天发布的作业) 24 | # :param days: 最近几天的作业(当 assignment_type 为 days 时,必须输入 days) 25 | """ 26 | 27 | global resQueryset, res_end_time_Queryset, res_end_time_null_Queryset 28 | assignment_type = request.GET.get( 29 | 'assignment_type', default='all_effective') 30 | 31 | # 获取数据库信息 32 | this_week_start = datetime.now() - timedelta(days=datetime.now().weekday()) # 星期一日期 33 | if assignment_type == 'info': 34 | info = [ 35 | 'assignment_type: 获取作业类型(info:使用说明,week:本周未超时作业,all_effective:所有未超时),today:当天发布的作业)
', 37 | 'days: 最近几天的作业(当 assignment_type 为 days 时,必须输入 days 参数,表示最近几天)
' 38 | ] 39 | response = '\n'.join(info) 40 | return HttpResponse(response) 41 | elif assignment_type == 'all_effective': 42 | cur_date = datetime.now().date() 43 | 44 | res_end_time_Queryset = AssignmentInfo.objects.filter( 45 | end_time__isnull=False, end_time__gte=cur_date) 46 | res_end_time_null_Queryset = AssignmentInfo.objects.filter( 47 | end_time__isnull=True, start_time__gte=this_week_start) 48 | 49 | elif assignment_type == 'week': 50 | cur_date = datetime.now() 51 | this_week_end = datetime.now() - timedelta(days=datetime.now().weekday() - 6) 52 | print(this_week_end) 53 | res_end_time_Queryset = AssignmentInfo.objects.filter( 54 | Q(end_time__isnull=False, start_time__gte=this_week_start, end_time__gte=cur_date) | 55 | Q(end_time__isnull=False, end_time__gte=cur_date, 56 | end_time__lte=this_week_end) 57 | ) 58 | 59 | res_end_time_null_Queryset = AssignmentInfo.objects.filter(end_time__isnull=True, 60 | start_time__gte=this_week_start) 61 | elif assignment_type == 'days': 62 | cur_date = datetime.now() 63 | days = request.GET.get('days', default=None) 64 | if days: 65 | day = cur_date + timedelta(days=int(days)) 66 | print(day) 67 | res_end_time_Queryset = AssignmentInfo.objects.filter( 68 | end_time__isnull=False, end_time__lte=day, end_time__gte=cur_date) 69 | res_end_time_null_Queryset = AssignmentInfo.objects.none() 70 | 71 | else: 72 | return HttpResponseNotFound(content='