(项目)在线教育平台(六)

八、授课机构功能

1、模板继承

  如果几个页面的大体结构相同,可以使用继承的方式来实现母版的重用性,也就是子版继承母版的内容,既可以使用模板的内容,也可以重写需要改变的地地方。

  首先完成授课机构的页面,通过页面显示发现,

  先把org-list.html页面拷贝到templates下,在该目录下新建base.html页面,然后将org-list.html内容剪切到base.html下,然后修改静态文件的路径,在base.html页面下找到需要block的地方,以供子版继承重写:

  org-list.html继承base.html,自定义org-list.html页面中的内容:

  base.html页面还需要修改的地方是顶部登录注册的显示问题,这个问题和index.html页面的一样,只需要将index页面的拷贝过来即可。

2、后端机构列表接口

2.1 机构列表接口

  在organization/views.oy文件下编写机构列表的接口:

1 class OrgView(View):
2     """机构列表"""
3     def get(self, request):
4         return render(request, 'org-list.html')

  配置url:

1 from organization.views import OrgView
2 
3 urlpatterns = [
4     path('org_list/', OrgView.as_view(), name='org_list')  # 机构列表
5 ]

  然后修改index.html导航栏跳转到机构列表的url:

  现在访问机构列表页就可以看到页面了。

2.2 后台添加数据

  后台添加城市的相关数据:

  后台添加机构的相关数据,不过需要先在organization/models.py机构中添加一个字段category,用来区分机构的类别:

 1 class CourseOrg(models.Model):
 2     """课程机构"""
 3     CATEGORY_CHOICES = (
 4         ('pxjg', '培训机构'),
 5         ('gx', '高校'),
 6         ('gr', '个人')
 7     )
 8     name = models.CharField('机构名称', max_length=50)
 9     category = models.CharField('机构类别', max_length=20, choices=CATEGORY_CHOICES, default='pxjg')
10     desc = models.TextField('机构描述')
11     click_nums = models.IntegerField('点击数', default=0)
12     fav_nums = models.IntegerField('收藏数', default=0)
13     image = models.ImageField('封面图', upload_to='org/%Y/%m', max_length=100)
14     address = models.CharField('地址', max_length=150)
15     city = models.ForeignKey(CityDict, verbose_name='所在城市', on_delete=models.CASCADE)
16     add_time = models.DateTimeField('添加时间', default=datetime.now)
17 
18     class Meta:
19         verbose_name = '课程机构'
20         verbose_name_plural = verbose_name

  修改之后需要迁移数据库。

  在后台添加机构信息的时候需要上传机构的图片,在项目根目录下新建一个media,用来存放上传的图片,然后在settings.py文件中设置上传文件的路径:

1 # 上传文件的路径
2 MEDIA_URL = '/media/'
3 MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

  然后现在添加机构的数据:

2.3 完善机构列表的接口

 1 class OrgView(View):
 2     """机构列表"""
 3     def get(self, request):
 4         # 取出所有的机构
 5         all_orgs = CourseOrg.objects.all()
 6         org_nums = all_orgs.count()
 7 
 8         # 取出所有的城市
 9         all_citys = CityDict.objects.all()
10 
11         return render(request, 'org-list.html', {
12             'all_orgs': all_orgs,
13             'all_citys': all_citys,
14             'org_nums': org_nums
15         })

  然后修改前端org-list.html显示的内容:

  要显示后台的图片,需要在settings.py中的TEMPLATES添加图片处理器django.template.context_processors.media,如下:

 1 TEMPLATES = [
 2     {
 3         'BACKEND': 'django.template.backends.django.DjangoTemplates',
 4         'DIRS': [os.path.join(BASE_DIR, 'templates')]
 5         ,
 6         'APP_DIRS': True,
 7         'OPTIONS': {
 8             'context_processors': [
 9                 'django.template.context_processors.debug',
10                 'django.template.context_processors.request',
11                 'django.contrib.auth.context_processors.auth',
12                 'django.contrib.messages.context_processors.messages',
13                 # 图片处理器,为了在课程列表中前面加上MEDIA_URL
14                 'django.template.context_processors.media',
15             ],
16         },
17     },
18 ]

  然后在urls中配置处理图片的url,固定写法:

1 from django.views.static import serve
2 from MxOnline.settings import MEDIA_ROOT
3 
4 urlpatterns = [
5     re_path(r'^media/(?P<path>.*)', serve, {"document_root": MEDIA_ROOT}),  # 处理图片显示
6 ]

  现在刷新列表页即可看到如下效果:

3、分页功能

  机构如果超出每一页的数量,就需要使用分页,在这里使用第三方库django-pure-pagination来实现分页。

3.1 安装

  在虚拟环境中直接pip install django-pure-pagination

3.2 注册

  将pure_pagination注册进INSTALLED_APPS中:

1 INSTALLED_APPS = [
2     'pure_pagination',
3 ]

3.3 在机构列表接口加入分页逻辑

 1 class OrgView(View):
 2     """机构列表"""
 3     def get(self, request):
 4         # 取出所有的机构
 5         all_orgs = CourseOrg.objects.all()
 6         org_nums = all_orgs.count()
 7 
 8         # 取出所有的城市
 9         all_citys = CityDict.objects.all()
10 
11         # 分页
12         try:
13             page = request.GET.get('page', 1)
14         except PageNotAnInteger:
15             page = 1
16         p = Paginator(all_orgs, 5, request=request)
17         orgs = p.page(page)
18 
19         return render(request, 'org-list.html', {
20             'all_orgs': orgs,
21             'all_citys': all_citys,
22             'org_nums': org_nums
23         })

  然后修改org-list.html中的all_orgs:

  在org-list.html中修改前端分页显示的代码:

  刷新列表页后,每页显示5条机构:

4、筛选功能

4.1 城市筛选

  在机构列表接口中完善筛选数据的逻辑:

 1 class OrgView(View):
 2     """机构列表"""
 3     def get(self, request):
 4         # 取出所有的机构
 5         all_orgs = CourseOrg.objects.all()
 6         org_nums = all_orgs.count()
 7 
 8         # 取出所有的城市
 9         all_citys = CityDict.objects.all()
10 
11         # 筛选(从request中获取城市的id)
12         city_id = request.GET.get('city', '')
13         if city_id:
14             all_orgs = all_orgs.filter(city_id=int(city_id))
15 
16         # 分页
17         try:
18             page = request.GET.get('page', 1)
19         except PageNotAnInteger:
20             page = 1
21         p = Paginator(all_orgs, 5, request=request)
22         orgs = p.page(page)
23 
24         return render(request, 'org-list.html', {
25             'all_orgs': orgs,
26             'all_citys': all_citys,
27             'org_nums': org_nums,
28             'city_id': city_id
29         })

  前端显示的修改如下:

4.2 类别筛选

  继续在机构列表接口完善类别筛选功能:

 1 class OrgView(View):
 2     """机构列表"""
 3     def get(self, request):
 4         # 取出所有的机构
 5         all_orgs = CourseOrg.objects.all()
 6 
 7         # 取出所有的城市
 8         all_citys = CityDict.objects.all()
 9 
10         # 城市筛选(从request中获取城市的id)
11         city_id = request.GET.get('city', '')
12         if city_id:
13             all_orgs = all_orgs.filter(city_id=int(city_id))
14 
15         # 类别筛选(从request中获取机构类别ct)
16         category = request.GET.get('ct', '')
17         if category:
18             all_orgs = all_orgs.filter(category=category)
19 
20         # 筛选完再统计数量
21         org_nums = all_orgs.count()
22 
23         # 分页
24         try:
25             page = request.GET.get('page', 1)
26         except PageNotAnInteger:
27             page = 1
28         p = Paginator(all_orgs, 5, request=request)
29         orgs = p.page(page)
30 
31         return render(request, 'org-list.html', {
32             'all_orgs': orgs,
33             'all_citys': all_citys,
34             'org_nums': org_nums,
35             'city_id': city_id,
36             'category': category
37         })

  前端的显示修改内容如下:

  修改完成之后,筛选功能完成,可以根据类别和城市筛选机构:

4.3 机构排名筛选

  机构的排名按照点击量进行排名,在机构列表接口中添加排名筛选逻辑:

 1 class OrgView(View):
 2     """机构列表"""
 3     def get(self, request):
 4         # 取出所有的机构
 5         all_orgs = CourseOrg.objects.all()
 6 
 7         # 取出所有的城市
 8         all_citys = CityDict.objects.all()
 9 
10         # 排名筛选(根据点击量排名)
11         hot_orgs = all_orgs.order_by('-click_nums')[:3]
12 
13         # 城市筛选(从request中获取城市的id)
14         city_id = request.GET.get('city', '')
15         if city_id:
16             all_orgs = all_orgs.filter(city_id=int(city_id))
17 
18         # 类别筛选(从request中获取机构类别ct)
19         category = request.GET.get('ct', '')
20         if category:
21             all_orgs = all_orgs.filter(category=category)
22 
23         # 筛选完再统计数量
24         org_nums = all_orgs.count()
25 
26         # 分页
27         try:
28             page = request.GET.get('page', 1)
29         except PageNotAnInteger:
30             page = 1
31         p = Paginator(all_orgs, 5, request=request)
32         orgs = p.page(page)
33 
34         return render(request, 'org-list.html', {
35             'all_orgs': orgs,
36             'all_citys': all_citys,
37             'org_nums': org_nums,
38             'city_id': city_id,
39             'category': category,
40             'hot_orgs': hot_orgs
41         })

  然后修改前端显示代码:

4.4 学习人数和课程排名筛选

  首先在organization/models.py中的CourseOrg中加入students和course_nums两个字段:

 1 class CourseOrg(models.Model):
 2     """课程机构"""
 3     CATEGORY_CHOICES = (
 4         ('pxjg', '培训机构'),
 5         ('gx', '高校'),
 6         ('gr', '个人')
 7     )
 8     name = models.CharField('机构名称', max_length=50)
 9     category = models.CharField('机构类别', max_length=20, choices=CATEGORY_CHOICES, default='pxjg')
10     desc = models.TextField('机构描述')
11     students = models.IntegerField('学习人数', default=0)
12     course_nums = models.IntegerField('课程数', default=0)
13     click_nums = models.IntegerField('点击数', default=0)
14     fav_nums = models.IntegerField('收藏数', default=0)
15     image = models.ImageField('封面图', upload_to='org/%Y/%m', max_length=100)
16     address = models.CharField('地址', max_length=150)
17     city = models.ForeignKey(CityDict, verbose_name='所在城市', on_delete=models.CASCADE)
18     add_time = models.DateTimeField('添加时间', default=datetime.now)
19 
20     class Meta:
21         verbose_name = '课程机构'
22         verbose_name_plural = verbose_name
23 
24     def __str__(self):
25         return self.name

  然后迁移数据库。

  然后在机构列表接口中完善学习人数和课程数排名的逻辑:

 1 class OrgView(View):
 2     """机构列表"""
 3     def get(self, request):
 4         # 取出所有的机构
 5         all_orgs = CourseOrg.objects.all()
 6 
 7         # 取出所有的城市
 8         all_citys = CityDict.objects.all()
 9 
10         # 排名筛选(根据点击量排名)
11         hot_orgs = all_orgs.order_by('-click_nums')[:3]
12 
13         # 学习人数和课程数排名筛选
14         sort = request.GET.get('sort', '')
15         if sort:
16             if sort == 'students':
17                 all_orgs = all_orgs.order_by('-students')
18             elif sort == 'courses':
19                 all_orgs = all_orgs.order_by('-course_nums')
20 
21         # 城市筛选(从request中获取城市的id)
22         city_id = request.GET.get('city', '')
23         if city_id:
24             all_orgs = all_orgs.filter(city_id=int(city_id))
25 
26         # 类别筛选(从request中获取机构类别ct)
27         category = request.GET.get('ct', '')
28         if category:
29             all_orgs = all_orgs.filter(category=category)
30 
31         # 筛选完再统计数量
32         org_nums = all_orgs.count()
33 
34         # 分页
35         try:
36             page = request.GET.get('page', 1)
37         except PageNotAnInteger:
38             page = 1
39         p = Paginator(all_orgs, 5, request=request)
40         orgs = p.page(page)
41 
42         return render(request, 'org-list.html', {
43             'all_orgs': orgs,
44             'all_citys': all_citys,
45             'org_nums': org_nums,
46             'city_id': city_id,
47             'category': category,
48             'hot_orgs': hot_orgs,
49             'sort': sort
50         })

  然后修改前端代码:

5、我要学习咨询功能

5.1 我要学习咨询接口

  我要学习咨询的表单这次使用ModelForm来实现,首先在organization下新建form.py文件:

1 from django import forms
2 from operation.models import UserAsk
3 
4 
5 class UserAskForm(forms.ModelForm):
6     """我要学习咨询表单验证"""
7     class Meta:
8         model = UserAsk
9         fields = ['name','mobile','course_name']

  编写我要学习咨询的后台接口:

 1 class UserAskView(View):
 2     """我要学习咨询"""
 3     def post(self, request):
 4         userask_form = UserAskForm(request.POST)
 5         if userask_form.is_valid():
 6             # 通过ModelForm可以直接将表单中的内容保存
 7             user_ask = userask_form.save(commit=True)
 8             # 通过ajax提交,给前端返回json数据
 9             return HttpResponse('{"status": "success"}', content_type='application/json')
10         else:
11             return HttpResponse('{"status": "fail", "msg": "添加出错"}', content_type='application/json')

  现在使用路由分发的方式来配置url,首先删除urls.py中的org_list这个路由,然后添加一级路由:

1 urlpatterns = [
2     # path('org_list/', OrgView.as_view(), name='org_list'),  # 机构列表
3     path('org/', include('organization.urls', namespace='org')),  # 机构列表
4 ]

  然后在organization下新建urls.py文件,在这个文件配置机构列表页的相关url,之前删除了机构列表的url,现在将机构列表和我要学习咨询的url都添加到这个文件下:

 1 from django.urls import path, re_path
 2 
 3 from .views import OrgView, UserAskView
 4 
 5 app_name = 'organization'
 6 
 7 urlpatterns = [
 8     path('list/',OrgView.as_view(),name='org_list'),  # 机构列表
 9     path('user_ask/', UserAskView.as_view(), name='user_ask'),  # 我要学习咨询
10 ]

  之前在首页跳转机构列表的url需要修改过来:

  然后在form中添加验证手机号码合法性的逻辑:

 1 import re
 2 
 3 from django import forms
 4 from operation.models import UserAsk
 5 
 6 
 7 class UserAskForm(forms.ModelForm):
 8     """我要学习咨询表单验证"""
 9     class Meta:
10         model = UserAsk
11         fields = ['name','mobile','course_name']
12 
13     def clean_mobile(self):
14         """验证手机号合法性"""
15         mobile = self.cleaned_data['mobile']
16         REGEX_MOBILE = "^1[358]\d{9}$|^147\d{8}$|176\d{8}$"
17         p = re.compile(REGEX_MOBILE)
18         if p.match(mobile):
19             return mobile
20         else:
21             raise forms.ValidationError('手机号非法', code='mobile_invalid')

  我要学习咨询表单是将数据ajax提交到后台的,不刷新页面,所以在前端要编写script代码:

 

转载于:https://www.cnblogs.com/Sweltering/p/9973522.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/450674.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言 socket 编程学习

对于SOCKET在这里我不想究其历史,我只想说其时它是一种进程通讯的方式,简言之就是调用这个网络库的一些API函数就能实现分布在不同主机的相关进程之间的数据交换. SOCKET中首先我们要理解如下几个定义概念: 一是IP地址:IP Address我想很容易理解,就是依照TCP/IP协议分配…

dependency 中的 classifier属性

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 classifier元素用来帮助定义构件输出的一些附属构件。附属构件与主构件对应&#xff0c;比如主构件是 kimi-app-2.0.0.jar 该项目可能还…

PHP超全局变量$_SERVER

$_SERVER 是一个包含了诸如头信息(header)、路径(path)、以及脚本位置(script locations)等等信息的数组。这个数组中的项目由 Web 服务器创建。不能保证每个服务器都提供全部项目&#xff1b;服务器可能会忽略一些&#xff0c;或者提供一些没有在这里列举出来的项目。 $_SERVE…

VC读写XML文件

1、安装MSXML 4.0 SP2。在VC6中建立一个基于Dialog的工程。如图&#xff1a; 在界面上放置3个编辑框、1个按钮控件。其中属性设置如下。 编辑框&#xff1a; IDCategoryVariable TypeVariable NameIDC_IDValueCStringm_strIdIDC_AUTHORValueCStringm_strAuthorIDC_TITLEValueCS…

XCode10 swift4.2 适配遇到的坑

以下是2018年10月23日更新 经过大约一个月的时间的适配&#xff0c;项目正式使用XCode10(以下简称为10 or XC10)大部分库都升级为Swift4.2&#xff08;以下简称为 4.2 or S4.2&#xff09;&#xff0c;下面是适配过程中遇到的一些坑。 1. Swift4、Swift4.2混编 如果你对项目是小…

学生管理系统Java版

简单的学生管理系统 主界面编写&#xff1a; 1.用输出语句完成主界面的编写 2.用Scanner语句实现键盘的录入 3.用swich语句完成操作的选择 4.用循环完成再次回到主界面 代码实现&#xff1a; while (true) {//1.用输出语句完成主界面的编写System.out.println("--------…

dubbo 配置文件详解

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 一、dubbo常用配置 <dubbo:service/> 服务配置&#xff0c;用于暴露一个服务&#xff0c;定义服务的元信息&#xff0c;一个服务可…

ASP.NET Core 实战:Linux 小白的 .NET Core 部署之路

一、前言 最近一段时间自己主要的学习计划还是按照毕业后设定的计划&#xff0c;自己一步步的搭建一个前后端分离的 ASP.NET Core 项目&#xff0c;目前也还在继续学习 Vue 中&#xff0c;虽然中间断了很长时间&#xff0c;好歹还是坚持下来了&#xff0c;嗯&#xff0c;看了看…

学以致用十三-----Centos7.2+python3+YouCompleteMe成功历程

历经几天的摸索&#xff0c;趟过几趟坑之后&#xff0c;终于完成YouCompleteMe的安装配置。 今天同样是个不能忘记的日子&#xff0c;国耻日&#xff0c;勿忘国耻。&#xff08;9.18&#xff09; 服务器安装好&#xff0c;基本配置配置好后&#xff0c;开始安装。 一、检查服务…

VC画图用到的主要方法

1。鼠标落下&#xff0c;记录鼠标的起始位置 void CMyEasyDrawView::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: 在此添加消息处理程序代码和/或调用默认值 //graph->m_nTypedlg-> m_bStartDraw true; m_PtPress m_PtLast point; CView::OnLButtonDown…

【最新版】Java学习路线(含B站口碑推荐视频链接)

文章目录关于如何自学一、计算机网络二、数据结构与算法三、操作系统四、计算机组成原理五、编译原理六、设计模式七、MySQL八、实操工具九、JAVA并发与JVM十、Redis十一、Linux十二、Java路线学习尚硅谷黑马程序员动力节点狂神说十三、Java基础十四、JavaWeb十五、框架十六、微…

记录no static method cannot be reference

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 报错如题&#xff1a; no static method cannot be reference 我一直以为是在静态方法中调用了非静态方法&#xff0c;实际上只是我在注…

文件存储权限

Android 6.0及以上&#xff0c;需要动态申请权限&#xff1a; Manifest.permission.READ_EXTERNAL_STORAGE Manifest.permission.WRITE_EXTERNAL_STORAGE <uses-permission-sdk-23 android:name"android.permission.WRITE_EXTERNAL_STORAGE" /><uses-permis…

从工具的奴隶到工具的主人

摘要&#xff1a;我们每个人都是工具的奴隶。随着我们的学习&#xff0c;我们不断的加深自己对工具的认识&#xff0c;从而从它们里面解脱出来。现在我就来说一下我作为各种工具的奴隶&#xff0c;以及逐渐摆脱它们的思想控制的历史吧。 当我高中毕业进入大学计算机系的时候&am…

记录A component required a bean named ‘studentService‘ that could not be found.

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 报错如题&#xff1a; A component required a bean named studentService that could not be found. 出问题的代码行&#xff1a; &l…

Java---利用程序实现在控制台聊天

一.普通版&#xff08;不能实现随意输入&#xff09; 电脑A(服务器端) package day; import java.net.ServerSocket; import java.net.Socket; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Scanner;public class Mysever {public static void…

16.看板方法——三类改进机会笔记

00.三种常见的模型和它们一些变种&#xff1a;约束理论及其主要理念&#xff1b;还有聚焦于分析和减少变异性的模型及其变种等。 01.五步聚焦法 *a.识别约束 *b.作出决定&#xff0c;以最大化利用约束 *c.使系统中的其余一切部分都服从于b中做出决定 *d.突破约束 *e.避免惰性&a…

C/C++的64位整型

在C/C中&#xff0c;64为整型一直是一种没有确定规范的数据类型。现今主流的编译器中&#xff0c;对64为整型的支持也是标准不一&#xff0c;形态各异。一般来说&#xff0c;64位整型的定义方式有long long和__int64两种(VC还支持_int64)&#xff0c;而输出到标准输出方式有pri…

记录 Duplicate spring bean id dubbo

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 启动工程 报错如题&#xff1a; Duplicate spring bean id dubbo &#xff0c;意思是id 重复。 原因是我在加载配置文件时加载了两个…

1.KafKa-介绍

转载于:https://www.cnblogs.com/v-lcc/p/9674975.html