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

八、授课机构功能

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,一经查实,立即删除!

相关文章

dependency 中的 classifier属性

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

VC读写XML文件

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

学生管理系统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;开始安装。 一、检查服务…

记录 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

研究显示每天工作超8小时得心脏病概率增加80%,生命很重要,工作不要那个累。

每天工作超过8小时的人患心脏病的风险最高可增加80%(资料图) 据英国《每日邮报》9月12日报道&#xff0c;芬兰职业保健研究所的科学家们近日进行了一项研究&#xff0c;他们发现每天工作超过8小时的人患心脏病的风险最高可增加80%。 研究人员表示&#xff0c;长时间的工作是许多…

沉淀再出发:Spring的架构理解

沉淀再出发:Spring的架构理解 一、前言 在Spring之前使用的EJB框架太庞大和重量级了&#xff0c;开发成本很高&#xff0c;由此spring应运而生。关于Spring&#xff0c;学过java的人基本上都会慢慢接触到&#xff0c;并且在面试的时候也是经常遇到的&#xff0c;因为这个技术极…

CentOS 7 搭建CA认证中心实现https取证

CA认证中心简述CA &#xff1a;CertificateAuthority的缩写&#xff0c;通常翻译成认证权威或者认证中心&#xff0c;主要用途是为用户发放数字证书功能&#xff1a;证书发放、证书更新、证书撤销和证书验证。作用&#xff1a;身份认证&#xff0c;数据的不可否认性端口&#x…

简单明了 - Git 使用超详细教程

见&#xff1a;http://www.admin10000.com/document/5374.html 一&#xff1a;Git是什么&#xff1f; Git是目前世界上最先进的分布式版本控制系统。 二&#xff1a;SVN与Git的最主要的区别&#xff1f; SVN是集中式版本控制系统&#xff0c;版本库是集中放在中央服务器的&…

FileStream功能被禁用

今天还原数据库&#xff0c;遇到如下问题&#xff1a; 网上的解决方法大概是三种&#xff1a; 1、讲数据库备份文件权限设置为“EventOne” 2、打开SQLServer配置管理器&#xff0c;选中服务然后右击“属性”将FileStream相关勾选并重启当前实例服务 3、设置数据库访问级别 USE…

window.parent,top,window.self,parent,opener

2019独角兽企业重金招聘Python工程师标准>>> 在应用有frameset或者iframe的页面时&#xff0c;parent是父窗口&#xff0c;top是最顶级父窗口&#xff08;有的窗口中套了好几层frameset或者iframe&#xff09;&#xff0c;self是当前窗口&#xff0c; opener是用ope…

ALM 中查看某个 test 的更改 history 历史

ALM 中要查看某个 test 更改历史&#xff0c; 需要下面两个表&#xff1a;AUDIT_LOG and AUDIT_PROPERTIES------- Get Test modification history -------- ---- In ALM, 857, if filter out test case named 26169502, check its History. In the history, for the node of d…

zookeeper使用和原理探究

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 zookeeper介绍 zookeeper是一个为分布式应用提供一致性服务的软件&#xff0c;它是开源的Hadoop项目中的一个子项目&#xff0c;并且根据…

thinkphp如何部署到宝塔面板nginx服务器

原理&#xff1a;一般本地都会使用apache服务器&#xff0c;这个对pathinfo&#xff08;两个&#xff0c;一个是环境变量$_SERVER[PATH_INFO]&#xff0c;另一个是pathinfo函数&#xff09;路由解析非常支持的&#xff0c;不需要部署什么&#xff0c; 但是nginx是对pathinfo函…

nginx的脚本引擎(一)

nginx的脚本的语法和shell是很像的&#xff0c;我大致看了一下觉得挺有意思的&#xff0c;就想写写记录一下。我没看过shell脚本的引擎&#xff0c;不知道nginx脚本引擎和shell脚本引擎像不像&#xff0c;但是我觉得nginx的脚本引擎有点像C和汇编。 ngx_http_script_engine_t这…

一个待办事列表todolist

最近有位老师让我做的&#xff0c;图片在下面&#xff0c;做了4个多小时&#xff0c;ui有的简陋&#xff0c;可以再美化一下&#xff0c;这个会更好看&#xff0c;毕竟我也不是专业前端&#xff0c;测试网站http://todolist.sshouxin.top/使用的是thinkphp5.1的框架&#xff0c…

详细说明 SourceTree 免登录,跳过初始设置的方法(Windows 版 )

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 1. 首先&#xff0c;安装完 SourceTree 以后先运行一次&#xff0c;弹出初始化登录页面后退出。 2. 进入这个文件夹&#xff1a;C:\Users…