学习自慕课网-使用python3.x与Django2.0.1开发的在线教育平台
(1)创建母板
把org-list.html拷贝到templates目录下,新建base.html,剪切org-list.html内容到里面
再修改一下静态文件的地址(css、就是、image和media)
(2)机构首页路由
fromorganization.viewsimportOrgViewpath('org_list/',OrgView.as_view(),name='org_list'),(3)机构views
classOrgView(View):'''课程机构'''defget(self,request):returnrender(request,'org-list.html')(4)org-list.html继承base
(5)修改base模板
把base中custom_bread和content两个block的内容剪切到org-list.html里面
base.html
org-list.html
(1)进xadmin后台添加城市
这里机构是静态固定不变的,所在地区是动态的,从数据库中获取得到的
(2)修改机构的models,添加一个机构类别字段
organization/models.py:
(3)添加机构
添加机构信息的时候要上传机构的图片
在项目目录下面新建一个目录“media”,用来存放上传的图片
setting中要配置我们把文件存放在哪个根目录之下
#settings.py#设置上传文件的路径MEDIA_URL='/media/'MEDIA_ROOT=os.path.join(BASE_DIR,'media')#指定根目录会跟upload里面拼接完整的路径
“/media/org/2018/月份/图片名字”
然后在后台添加十个机构
(1)写视图函数organization/views.py
classOrgView(View):'''课程机构'''defget(self,request):#取出所有课程机构all_orgs=CourseOrg.objects.all()org_onums=all_orgs.count()#取出所有城市all_citys=CityDict.objects.all()returnrender(request,"org-list.html",{"all_orgs":all_orgs,"all_citys":all_citys,'org_onums':org_onums,})(2)修改org-list.html
显示机构总共数量
显示城市
显示机构
然后还要做下面的设置
如何将imageField转换成图片地址
数据库中image以字符串格式保存的,是相对路径,直接取是取不出来的,必须补全路径
data-url="{{MEDIA_URL}}{{course_org.image}}"MEDIA_URL='/media/',这个是之前settings中设置好了要向使用{{MEDIA_URL}},要先在settings中TEMPLATES里面添加media处理器:'django.core.context_processors.media'
然后也要添加处理图片相应路径的url
TEMPLATES=[{'BACKEND':'django.template.backends.django.DjangoTemplates','DIRS':[os.path.join(BASE_DIR,'templates')],'APP_DIRS':True,'OPTIONS':{'context_processors':['django.template.context_processors.debug','django.template.context_processors.request','django.contrib.auth.context_processors.auth','django.contrib.messages.context_processors.messages',#添加图片处理器,为了在课程列表中前面加上MEDIA_URL'django.template.context_processors.media',],},},]urls.py
fromdjango.views.staticimportservefromMxOnline.settingsimportMEDIA_ROOT#处理图片显示的url,使用Django自带serve,传入参数告诉它去哪个路径找,我们有配置好的路径MEDIAROOTre_path(r'^media/(P
(1)安装
pipinstalldjango-pure-pagination(2)settings里面添加
INSTALLED_APPS=(...'pure_pagination',)(3)views中使用方法
classOrgView(View):'''课程机构'''defget(self,request):#所有课程机构all_orgs=CourseOrg.objects.all()#有多少家机构org_nums=all_orgs.count()#所有城市all_citys=CityDict.objects.all()#对课程机构进行分页#尝试获取前台get请求传递过来的page参数#如果是不合法的配置参数默认返回第一页try:page=request.GET.get('page',1)exceptPageNotAnInteger:page=1#这里指从allorg中取五个出来,每页显示5个p=Paginator(all_orgs,5,request=request)orgs=p.page(page)returnrender(request,"org-list.html",{"all_orgs":orgs,"all_citys":all_citys,"org_nums":org_nums,})(4)修改org-list.html
这里变成"all_orgs.object_list"
分页功能
(1)城市列表筛选
后台处理city筛选
classOrgView(View):'''课程机构'''defget(self,request):#所有课程机构all_orgs=CourseOrg.objects.all()#有多少家机构org_nums=all_orgs.count()#所有城市all_citys=CityDict.objects.all()city_id=request.GET.get('city','')ifcity_id:all_orgs=all_orgs.filter(city_id=int(city_id))#对课程机构进行分页#尝试获取前台get请求传递过来的page参数#如果是不合法的配置参数默认返回第一页try:page=request.GET.get('page',1)exceptPageNotAnInteger:page=1#这里指从allorg中取五个出来,每页显示5个p=Paginator(all_orgs,2,request=request)orgs=p.page(page)returnrender(request,"org-list.html",{"all_orgs":orgs,"all_citys":all_citys,"org_nums":org_nums,'city_id':city_id,})前端页面
{%ifequalcity_id''%}如果为空,说明没有city选中,则“全部”是“active”
(2)类别筛选
后台处理
#类别筛选category=request.GET.get('ct','')ifcategory:all_orgs=all_orgs.filter(category=category)#有多少家机构org_nums=all_orgs.count()把org_numsf放到后面,先筛选在统计数量
模板中
(3)课程机构排名筛选
按点击量排名,只取前三个
(4)学习人数和课程的筛选
在models中添加学习人数和课程数两个字段
#学习人数和课程数筛选sort=request.GET.get('sort',"")ifsort:ifsort=="students":all_orgs=all_orgs.order_by("-students")elifsort=="courses":all_orgs=all_orgs.order_by("-course_nums")
前端
(1)用ModelForm来实现
在organazition目录下创建forms.py文件
#organization/forms.pyfromdjangoimportformsfromoperation.modelsimportUserAskclassUserAskForm(forms.Form):'''我要咨询'''classMeta:model=UserAskfields=['name','mobile','course_name'](2)include路由分发
path("org/",include('organization.urls',namespace="org")),使用命名空间防止重复
然后在organization/urls.py中添加
#organization/urls.pyfromorganization.viewsimportOrgViewfromdjango.urlsimportpath,re_path#要写上app的名字app_name="organization"urlpatterns=[path('list/',OrgView.as_view(),name='org_list'),]html中使用命名空间的方式:
修改base.html中“课程机构的链接”
HttpResponse可以指定传递到前端的数据类型
(4)配置url
#organization/urls.pyfromorganization.viewsimportOrgView,AddUserAskViewfromdjango.urlsimportpath,re_path#要写上app的名字app_name="organization"urlpatterns=[path('list/',OrgView.as_view(),name='org_list'),path('add_ask/',AddUserAskView.as_view(),name="add_ask"),](5)在ModelForm中自定义一个手机号验证的方法
#organization/forms.pyimportrefromdjangoimportformsfromoperation.modelsimportUserAskclassUserAskForm(forms.ModelForm):classMeta:model=UserAskfields=['name','mobile','course_name']defclean_mobile(self):"""验证手机号码是否合法"""mobile=self.cleaned_data['mobile']REGEX_MOBILE="^1[358]\d{9}$|^147\d{8}$|176\d{8}$"p=re.compile(REGEX_MOBILE)ifp.match(mobile):returnmobileelse:raiseforms.ValidationError(u"手机号码非法",code="mobile_invalid")(6)模板中使用Ajax方式提交
提交数据不合法时
合法时,提示成功信息,数据保存到数据库
(1)给courses添加一个外键
(2)模板
把课程机构页面的四个文件拷贝到templates目录下
新建一个模板,命名为“org_base.html”,复制org-detail-homepage.html的内容到里面
添加block,修改静态文件路径
把org_base中的三个“right”剪切到home里面
(4)home页面的url
from.viewsimportOrgHomeViewre_path('home/(P
classOrgHomeView(View):'''机构首页'''defget(self,request,org_id):#根据id找到课程机构course_org=CourseOrg.objects.get(id=int(org_id))#反向查询到课程机构的所有课程和老师all_courses=course_org.course_set.all()[:4]all_teacher=course_org.teacher_set.all()[:2]returnrender(request,'org-detail-homepage.html',{'course_org':course_org,'all_courses':all_courses,'all_teacher':all_teacher,})(6)显示全部课程
(6)修改org-base.html
(7)为teacher添加一个图形字段
image=models.ImageField(default='',upload_to="teacher/%Y/%m",verbose_name="头像",max_length=100)(8)显示机构教师
(9)显示机构详情
机构首页:
(1)模板文件
把org-detail-course.html中不同的地方(right)取出来
(2)添加url
re_path('course/(P
classOrgCourseView(View):"""机构课程列表页"""defget(self,request,org_id):#根据id取到课程机构course_org=CourseOrg.objects.get(id=int(org_id))#通过课程机构找到课程。内建的变量,找到指向这个字段的外键引用all_courses=course_org.course_set.all()returnrender(request,'org-detail-course.html',{'all_courses':all_courses,'course_org':course_org,})(4)修改org-base.html中left的链接
(5)显示机构课程,修改org-detail-course.html
(6)左侧“active”状态修改
因为现在没有值能判断当前是哪个页面。所以在后台传个currentpage参数
修改org_base.html
(1)url
(2)views
classOrgDescView(View):'''机构介绍页'''defget(self,request,org_id):current_page='desc'#根据id取到课程机构course_org=CourseOrg.objects.get(id=int(org_id))returnrender(request,'org-detail-desc.html',{'course_org':course_org,'current_page':current_page,})7.10.机构讲师(1)url
re_path('teacher/(P
classOrgTeacherView(View):"""机构教师页"""defget(self,request,org_id):current_page='teacher'course_org=CourseOrg.objects.get(id=int(org_id))all_teacher=course_org.teacher_set.all()returnrender(request,'org-detail-teachers.html',{'all_teacher':all_teacher,'course_org':course_org,'current_page':current_page,})(3)org-detail-teachers.html
(4)org-bae.html中left
(5)修改面包屑,点机构课程应该显示机构课程
然后分别在其它四个页面中重载page_path
其它三个方法一样
Ajax放在org_base.html里面
可以在数据库中看到用户的收藏
(4)但是还有个问题就是,刷新页面后,“已收藏”就变成“收藏”,是因为在返回页面的时候,没有判断收藏状态
所有要在views里面加个判断
#判断收藏状态has_fav=Falseifrequest.user.is_authenticated:ifUserFavorite.objects.filter(user=request.user,fav_id=course_org.id,fav_type=2):has_fav=True