Django慕课网实战 -- 前端页面列表页显示、分页、筛选、排序、‘我要学习’模块提交(ajax)、机构详情页、机构收藏功能(ajax)

课程机构列表页数据显示

step1: 在organization app中的views.py文件中创建OrgView类

from django.shortcuts import render
from django.views.generic.base import View
from .models import CourseOrg, CityDict
# Create your views here.

class OrgView(View):
    """
    课程机构列表功能
    """
    def get(self, request):
        # 获取所有机构信息
        all_orgs = CourseOrg.objects.all()
        # 获取所有城市信息
        all_citys = CityDict.objects.all()
        return render(request, 'org-list.html', {'all_orgs': all_orgs, 'all_citys': all_citys})

step2:urls.py

from django.urls import path, re_path, include
from django.views.generic import TemplateView  # 使用静态模板 不需要在app下面的views.py文件中配置render
from users import views as users_views
from organization import views as org_views
from django.views.static import serve  # 处理静态文件
from MxOnline.settings import MEDIA_ROOT
import xadmin

urlpatterns = [
    ...
    re_path('^org_list/$', org_views.OrgView.as_view(), name='org_list'),
    # 配置上传文件的访问处理函数
    re_path('^media/(?P<path>.*)$', serve, {'document_root': MEDIA_ROOT}),
]

step3:在MxOnline目录下新建一个media文件夹,用于存储机构logo图片

step4:然后再setting.py中配置此路径,添加如下代码:

MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

step5:配置前端显示页面org-list.html

{% for org in all_orgs %}
    <dl class="des difdes">
        <dt>
            <a href="org-detail-homepage.html">
                <img width="200" height="120" class="scrollLoading" data-url="{{ MEDIA_URL }}{{ org.image }}"/>
            </a>
        </dt>
        <div class="buy start_groupbuy jsShowPerfect2" data-id="22"><br/>联系<br/>服务</div>
    </dl>
{% endfor %}

step6:上面html文件中引用了setting.py里的MEDIA_URL参数,需要把根目录下的media文件路径配置到html页面中。即在setting.py文件中添加如下配置

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                ...
                'django.template.context_processors.media',  # 把根目录下的media文件路径配置到html页面中
            ],
        },
    },
]

step7:此时发现前端页面中的图片还是无法正常显示,因为需要在url中配置django处理静态文件

from django.views.static import serve  # 处理静态文件
from MxOnline.settings import MEDIA_ROOT
import xadmin

urlpatterns = [
    ...
    # 配置上传文件的访问处理函数
    re_path('^media/(?P<path>.*)$', serve, {'document_root': MEDIA_ROOT}),
]

此时显示如下:

列表分页功能 -- Paginator

Django 是自带 分页功能(Paginator)的,但是功能不太丰富。pure pagination是在django自带的Paginator基础上进一步的封装。

分页理由:比如上面的OrgView类中 all_orgs = CourseOrg.objects.all()。假设数据库中有1000条数据,这时候不能直接把这1000条数据直接返回给all_orgs的,因为这样会在前端页面上直接显示这1000条数据。所以需要先分页。

 

GitHub链接 :https://github.com/jamespacileo/django-pure-pagination

step1:安装pure pagination

pip install django-pure-pagination

step2:Add pure_pagination to INSTALLED_APPS

INSTALLED_APPS = (
    ...
    'pure_pagination',
)

step3:修改OrgView类

from pure_pagination import Paginator, EmptyPage, PageNotAnInteger

class OrgView(View):
    """
    课程机构列表功能
    """
    def get(self, request):
        # 获取所有机构信息
        all_orgs = CourseOrg.objects.all()

        # 对课程机构进行分类
        try:
            page = request.GET.get('page', 1)
        except PageNotAnInteger:
            page = 1
        # Provide Paginator with the request object for complete querystring generation
        p = Paginator(all_orgs, 5, request=request)  # 每页5条记录
        orgs = p.page(page)

        org_nums = all_orgs.count()
        # 获取所有城市信息
        all_citys = CityDict.objects.all()
        return render(request, 'org-list.html', {
            'all_orgs': orgs,
            'all_citys': all_citys,
            'org_nums': org_nums,
        })

step4:前端页面配置

 <div class="pageturn">
    <ul class="pagelist">
        {% if all_orgs.has_previous %}
            <li class="long"><a href="?{{ all_orgs.previous_page_number.querystring }}">上一页</a></li>
        {% endif %}
        {% for page in all_orgs.pages %}
            {% if page %}
                {% ifequal page all_orgs.number %}
                    <li class="active"><a href="?{{ page.querystring }}">{{ page }}</a></li>
                {% else %}
                    <li><a href="?{{ page.querystring }}" class="page">{{ page }}</a></li>
                {% endifequal %}
            {% endif %}
        {% endfor %}
        {% if all_orgs.has_next %}
            <li class="long"><a href="?{{ all_orgs.next_page_number.querystring }}">下一页</a></li>
        {% endif %}
    </ul>
</div>

效果:

列表筛选功能

当用户点击前端页面上一个city名字的时候,我们通过get的方式,把该city的city.id传到后天app中的 视图 view中。

html中代码片段:

{% for city in all_citys %}
    <a href="?city={{ city.id }}"><span>{{ city }}</span></a>  <!--把city.id以get方式传到后台-->
{% endfor %}

然后再OrgView类中拿到该city_id

from django.shortcuts import render
from django.views.generic.base import View
from .models import CourseOrg, CityDict
from pure_pagination import Paginator, EmptyPage, PageNotAnInteger

class OrgView(View):
    """
    课程机构列表功能
    """
    def get(self, request):
        # 获取所有机构信息
        all_orgs = CourseOrg.objects.all()

        # 取出筛选 (用户点击的) 城市
        city_id = request.GET.get('city', '')  # 如果GET字典中没有city这个参数的话,默认返回空串
        if city_id:  # 如果有此参数,说明用户点击了某个city。然后就进行进一步过滤:即筛选出特定城市的org记录
            all_orgs = all_orgs.filter(city_id=int(city_id))

        # 对课程机构进行分类
        try:
            page = request.GET.get('page', 1)
        except PageNotAnInteger:
            page = 1
        # Provide Paginator with the request object for complete querystring generation
        p = Paginator(all_orgs, 1, request=request)  # 每页5条记录
        orgs = p.page(page)

        org_nums = all_orgs.count()
        # 获取所有城市信息
        all_citys = CityDict.objects.all()

        return render(request, 'org-list.html', {
            'all_orgs': orgs,
            'all_citys': all_citys,
            'org_nums': org_nums,
        })

效果如下:点击了北京市之后  -- 只有一条记录满足要求。

然后设置 所点击的城市 处于active激活状态。各个城市名 和 '全部' 只能有一个处于激活状态。处理方式如下:

<div class="cont">  <!-- 当city名没有被点击时,也就没有get方式的参数传递,此时city_id为空串,'全部'按钮被激活 -->
    <a href="?ct="><span class="{% ifequal '' city_id %}active2{% endifequal %}">全部</span></a>
        {% for city in all_citys %} <!-- 由于city.id是int类型,需要转化为str类型。 下面的stringformat过滤器可以转化为str类型-->
            <a href="?city={{ city.id }}">
                <span class="{% ifequal city_id city.id|stringformat:'i' %} active2 {% endifequal %}">{{ city }}</span>
            </a>
        {% endfor %}
</div>

效果:

机构类别筛选

html

<div class="cont">
    <a href="?city="><span class="active2">全部</span></a>
        <a href="?ct=pxjg"><span class="">培训机构</span></a>
        <a href="?ct=gx"><span class="">高校</span></a>
        <a href="?ct=gr"><span class="">个人</span></a>
</div>

view

class OrgView(View):
    """
    课程机构列表功能
    """
    def get(self, request):
        # 获取所有机构信息
        all_orgs = CourseOrg.objects.all()

        # 取出筛选 (用户点击的) 城市
        city_id = request.GET.get('city', '')  # 如果GET字典中没有city这个参数的话,默认返回空串
        if city_id:  # 如果有此参数,说明用户点击了某个city。然后就进行进一步过滤:即筛选出特定城市的org记录
            all_orgs = all_orgs.filter(city_id=int(city_id))

        # 类别筛选
        category = request.GET.get('ct', '')  # 如果GET字典中没有ct这个参数的话,默认返回空串
        if category:
            all_orgs = all_orgs.filter(category=category)

        # 对课程机构进行分类
        try:
            page = request.GET.get('page', 1)
        except PageNotAnInteger:
            page = 1
        # Provide Paginator with the request object for complete querystring generation
        p = Paginator(all_orgs, 5, request=request)  # 每页5条记录
        orgs = p.page(page)

        org_nums = all_orgs.count()
        # 获取所有城市信息
        all_citys = CityDict.objects.all()

        return render(request, 'org-list.html', {
            'all_orgs': orgs,
            'all_citys': all_citys,
            'org_nums': org_nums,
            'city_id': city_id,  # 将city_id传到前端与 每一条记录的city.id比对。相同的话将此city按钮置于激活状态。
            'category': category,
        })

效果:

为了让ct和city同时传到后台,修改html代码如下:

<li>
    <h2>机构类别</h2>
    <div class="cont">
        <a href="?city={{ city_id }}"><span class="{% ifequal '' category %}active2{% endifequal %}">全部</span></a>
            <a href="?ct=pxjg&city={{ city_id }}"><span class="{% ifequal 'pxjg' category %}active2{% endifequal %}">培训机构</span></a>
            <a href="?ct=gx&city={{ city_id }}"><span class="{% ifequal 'gx' category %}active2{% endifequal %}">高校</span></a>
            <a href="?ct=gr&city={{ city_id }}"><span class="{% ifequal 'gr' category %}active2{% endifequal %}">个人</span></a>
    </div>
</li>
<li>
    <h2>所在地区</h2>
    <div class="more">更多</div>
    <div class="cont">  <!-- 当city名没有被点击时,也就没有get方式的参数传递,此时city_id为空串,'全部'按钮被激活 -->
        <a href="?ct={{ category }}"><span class="{% ifequal '' city_id %}active2{% endifequal %}">全部</span></a>
            {% for city in all_citys %} <!-- 由于city.id是int类型,需要转化为str类型。 下面的stringformat过滤器可以转化为str类型-->
                <a href="?city={{ city.id }}&ct={{ category }}">
                    <span class="{% ifequal city_id city.id|stringformat:'i' %} active2 {% endifequal %}">{{ city }}</span>
                </a>
            {% endfor %}
    </div>
</li>

效果

授课机构排名 -- 排序功能

view  -- 调用了对象集合的排序函数 order_by()

class OrgView(View):
    """
    课程机构列表功能
    """
    def get(self, request):
        # 获取所有机构信息
        all_orgs = CourseOrg.objects.all()
        hot_orgs = all_orgs.order_by('click_nums')[:5]  # 筛选出点击量最多的5条机构记录
        ...
        return render(request, 'org-list.html', {
            ...
            'hot_orgs': hot_orgs,
        })

html  -- 前端页面 for 循环中用于计数的参数 {{ forloop.counter }}

<div class="right companyrank layout">
    <div class="head">授课机构排名</div>
    {% for org in hot_orgs %}
        <dl class="des">
            <dt class="num fl">{{ forloop.counter }}</dt>  <!--此参数是for循环中用于计数的-->
            <dd>
                <a href="/company/2/"><h1>{{ org.name }}</h1></a>
                <p>{{ org.address }}</p>
            </dd>
        </dl>
    {% endfor %}
</div>

效果:

按 学习人数 和 课程数 排序

需要在CourseOrg 的Model类中添加上述两个字段

    students = models.IntegerField(default=0, verbose_name='学习人数')
    course_nums = models.IntegerField(default=0, verbose_name='课程数')

迁移 和 生成表

html  -- 需要 机构类别 、 所在地区  选定以后, 再选 (学习人数 或者 课程数 或者 全部)之一的话,之前选的的 机构类别、所在地区 不会变化。

但是  (学习人数 或者 课程数 或者 全部)之一 选定的话,再选机构类别 或者 所在地区,则不管前面所选择的是什么,统一跳到'全部'按钮。

<div class="listoptions">
    <ul>
        <li>
            <h2>机构类别</h2>
            <div class="cont">
                <a href="?city={{ city_id }}"><span class="{% ifequal '' category %}active2{% endifequal %}">全部</span></a>
                    <a href="?ct=pxjg&city={{ city_id }}"><span class="{% ifequal 'pxjg' category %}active2{% endifequal %}">培训机构</span></a>
                    <a href="?ct=gx&city={{ city_id }}"><span class="{% ifequal 'gx' category %}active2{% endifequal %}">高校</span></a>
                    <a href="?ct=gr&city={{ city_id }}"><span class="{% ifequal 'gr' category %}active2{% endifequal %}">个人</span></a>
            </div>
        </li>
        <li>
            <h2>所在地区</h2>
            <div class="more">更多</div>
            <div class="cont">  <!-- 当city名没有被点击时,也就没有get方式的参数传递,此时city_id为空串,'全部'按钮被激活 -->
                <a href="?ct={{ category }}"><span class="{% ifequal '' city_id %}active2{% endifequal %}">全部</span></a>
                    {% for city in all_citys %} <!-- 由于city.id是int类型,需要转化为str类型。 下面的stringformat过滤器可以转化为str类型-->
                        <a href="?city={{ city.id }}&ct={{ category }}">
                            <span class="{% ifequal city_id city.id|stringformat:'i' %} active2 {% endifequal %}">{{ city }}</span>
                        </a>
                    {% endfor %}
            </div>
        </li>
    </ul>
</div>
<div class="all">共<span class="key">{{ org_nums }}</span>家</div>
        <div class="head">
            <ul class="tab_header">
                <li class="{% ifequal '' sort %}active{% endifequal %}"><a href="?ct={{ category }}&city={{ city_id }}">全部</a> </li>
                <li class="{% ifequal 'students' sort %}active{% endifequal %}"><a href="?sort=students&ct={{ category }}&city={{ city_id }}">学习人数 &#8595;</a></li>
                <li class="{% ifequal 'courses' sort %}active{% endifequal %}"><a href="?sort=courses&ct={{ category }}&city={{ city_id }}">课程数 &#8595;</a></li>
            </ul>
        </div>

view

class OrgView(View):
    """
    课程机构列表功能
    """
    def get(self, request):
        # 获取所有机构信息
        all_orgs = CourseOrg.objects.all()

        ...
        # 按 学习人数 和 课程数排序
        sort = request.GET.get('sort', '')
        # 并且 sort 传回前端页面 控制 学习人数 和 课程数 按钮的激活状态
        if sort == 'students':  # 按学习人数降序
            all_orgs = all_orgs.order_by('-students')
        elif sort == 'courses':  # 按课程数降序
            all_orgs = all_orgs.order_by('-course_nums')

        # 对课程机构进行分页
        try:
            page = request.GET.get('page', 1)
        except PageNotAnInteger:
            page = 1
        # Provide Paginator with the request object for complete querystring generation
        p = Paginator(all_orgs, 5, request=request)  # 每页5条记录
        orgs = p.page(page)

        org_nums = all_orgs.count()
        # 获取所有城市信息
        all_citys = CityDict.objects.all()

        return render(request, 'org-list.html', {
            ...
            'sort': sort,
        })

效果:

强大的ModelForm -- 提交我要学习

前面提到过:用户输入的信息,如用户名密码等 在存入数据库之前需要预判断一下是否满足要求,比如密码长度大于6位,手机号码必须为11位等等。 而这种预判断 我们之前是在各个app下面新建的forms.py文件中自定义Form类实现的。

除了自定义之外,django.forms下面有一个强大的类 -- ModelForm。 继承此类的话 就不需要自定义Form类了。

自定义Form类 如下:

from django import forms

class UserAskForm(forms.Form):
    """
    自定义Form类。
    """
    name = forms.CharField(required=True, min_length=2)
    mobile = forms.CharField(required=True, min_length=11, max_length=11)
    course_name = forms.CharField(required=True, min_length=2, max_length=50)

继承ModelForm类  -- 并且 除了可以选择性的引用UserAsk中的字段,也可以按需添加新的字段。

from django import forms
from operation.models import UserAsk

class DjangoUserAskForm(forms.ModelForm):  # 继承MedelForm类
    class Meta:
        model = UserAsk  # 传入Model类 -- UserAsk
        fields = ['name', 'mobile', 'course_name']  # 直接引用UserAsk类中的字段

 

配置organization app单独的urls文件

MxOnline  urls.py  ---- 添加namespace命名空间

# 配置 organization app的urls文件
re_path('^org/', include(('organization.urls', 'organization'), namespace='org')),

organization app 下面的 urls.py

from django.urls import path, re_path, include
from organization import views

urlpatterns = [

    path('list/', views.OrgView.as_view(), name='list'),
]

html中的url填写如下:(包含命名空间)

<li class="active" ><a href="{% url 'org:list' %}">授课机构</a></li>

注意:‘我要学习’ 表单的提交 是一种异步操作,不会刷新页面;并且如果某个field字段不满足要求时,应该会有错误提示。

实际上是一种Ajax操作,render函数返回的应该是json数据,而非某个html页面。(因为返回html页面会跳转到改页面。)

此处需要用到 django.http 下面的 HttpResponse 类

注意:这里有个深坑:在Django2中,HttpResponse 中返回json的格式如果按下面这样写,在前端页面无法被正确解析。这样会在ajax中一直执行 error函数,无法进入到 success函数。

return HttpResponse("{'status': 'fail', 'msg': '提交出错'}", content_type='application/json')

要写成下面的格式

return HttpResponse('{"status": "fail", "msg": "添加出错!"}', content_type='application/json')
class AddUserAskView(View):
    """
    用户添加咨询 -- 即填写'我要学习'表单
    """
    def post(self, request):
        userask_form = UserAskForm(data=request.POST)  # 实例化
        if userask_form.is_valid():
            # 不用逐个去除Form里面的field,而可以直接将POST表单数据保存到数据库中。
            user_ask = userask_form.save(commit=True)
            # 返回一个字符串,并指明格式为 json. (第二个参数为固定写法)
            return HttpResponse('{"status": "success"}', content_type='application/json')  # 注意此格式的写法,否则前端无法正确解析
        else:
            # 失败则返回对应的errors
            # return HttpResponse("{'status': 'fail', 'msg': {0}}".format(userask_form.errors))
            return HttpResponse('{"status": "fail", "msg": "添加出错!"}', content_type='application/json')

html中ajax写法:

<script>
    $(function(){
        $('#jsStayBtn').on('click', function(){
            {#alert($('#jsStayForm').serialize());#}
            $.ajax({
                cache: false,
                type: "POST",
                url:"{% url 'org:add_ask' %}",
                data:$('#jsStayForm').serialize(),
                async: true,
                success: function(data) {
                    alert(data);
                    if(data.status == 'success'){
                        $('#jsStayForm')[0].reset();
                        alert("提交成功")
                    }else if(data.status == 'fail'){
                        $('#jsCompanyTips').html(data.msg)
                    }
                },
                error: function(data) {  //后端传来的json数据无法正确解析的话会一直执行error函数
                    alert('异常!');
                    alert(data.status);
                },
            });
        });
    })
</script>

配置url

re_path('^add_ask/$', views.AddUserAskView.as_view(), name='add_ask'),

为了自动验证手机号是否合法,可以在view类中判断。但更方便合理的是在Form类中判断。在forms.py 对应的UserAskForm类中添加 clean_mobile方法(固定写法 'clean_' 加上 字段名 )

import re
from django import forms

from operation.models import UserAsk

class UserAskForm(forms.ModelForm):  # 继承MedelForm类
    class Meta:
        model = UserAsk  # 传入Model类 -- UserAsk
        fields = ['name', 'mobile', 'course_name']  # 直接引用UserAsk类中的字段

        def clean_mobile(self):
            """
            自动验证手机号是否合法的判断函数
            """
            mobile = self.cleaned_data['mobile']  # 固定用法,获取mobile字段
            # 验证手机号的正则表达式
            REGEX_MOBILE = "^((13[0-9])|(14[5,7])|(15[0-3,5-9])|(17[0,3,5-8])|(18[0-9])|166|198|199|(147))\\d{8}$"
            p = re.compile(REGEX_MOBILE)
            if p.match(mobile):  # 验证成功
                return mobile
            else:
                raise forms.ValidationError('手机号码非法', code='mobile_invalid')

效果:

机构详情页 -- 机构首页

view类  -- 需要传进 org_id参数

class OrgHomeView(View):
    """
    机构首页
    """
    def get(self, request, org_id):
        course_org = CourseOrg.objects.get(id=int(org_id))
        # 获取某机构所有课程的方法,这里只取前三个
        all_courses = course_org.course_set.all()[:3]
        all_teachers = course_org.teacher_set.all()[:3]
        return render(request, 'org-detail-homepage.html', {
            'all_courses': all_courses,
            'all_teachers': all_teachers,
            'course_org': course_org,  # 获取对应id的机构,机构内有logo、机构描述desc等字段。
        })

url

re_path('^home/(?P<org_id>\d+)/$', views.OrgHomeView.as_view(), name='org_home'),

org-list.html  -- 注意 额外参数传进来的用法。

<dt>
    <a href="{% url 'org:org_home' org.id %}">  <!--此处需要一个额外的参数-->
        <img width="200" height="120" class="scrollLoading" data-url="{{ MEDIA_URL }}{{ org.image }}"/>
    </a>
</dt>

org-detail-homepage.html

顶部机构名字及logo

<div class="middle companyheader">
    <div class="wp">
        <img class="fl" style="width: 112px;height: 103px" src="{{ MEDIA_URL }}{{ course_org.image }}"/>
        <div class="head fl">
            <h1>
                {{ course_org.name }}
                <img src="/static/images/authentication.png"/>
                <img src="/static/images/gold.png"/>
            </h1>
            <p class="fl">
                <span class="fl" style="margin-top:8px;color:#848484;">推荐指数: </span>
                <span class="precision company-credit" data-star-scope="5.0"></span>
                <span class="key">5.0</span>
            </p>
        </div>
        <div class="btn fr collectionbtn  notlogin 
             "data-favid="22" data-fav-type="1">
             收藏
        </div>
    </div>
</div>

全部课程

<div class="brief group_list">
    {% for course in all_courses %}
        <div class="module1_5 box">
            <a href="course-detail.html"><img width="214" src="{{ MEDIA_URL }}{{ course.image }}"/></a>
            <div class="des">
                <a href="course-detail.html"><h2>{{ course.name }}</h2></a>
                <span class="fl">课时:<i class="key">{{ course.learn_times }}</i></span>
                <span class="fr">参加人数:{{ course.students }}</span>
            </div>
            <div class="bottom">
                <span class="fl">{{ course.course_org }}</span>
                 <span class="star fr  notlogin
                    " data-favid="13"  data-fav-type="4">
                    {{ course.fav_nums }}  <!--收藏人数-->
                </span>
            </div>
        </div>
    {% endfor %}
</div>

机构教师

{% for teacher in all_teachers %}
    <div class="diarys">
        <div class="module5 share company-diary-box" style="padding:10px 0;">
            <div class="left">
                <img class="pic" src="{{ MEDIA_URL }}{{ teacher.image }}"/>
                <p>昵称:{{ teacher.name }}</p>
            </div>
            <div class="right">
                <div class="top">
                    <div class="fl">
                        <a href=""><h1>Django实战教程</h1></a>
                        <span>发表于:2018-11-29</span>
                    </div>
                </div>
                <div class="middle" style="border-bottom:0;">课程介绍</div>
            </div>
        </div>
    </div>
{% endfor %}

机构介绍

<div class="right companycenter layout" >
    <div class="head">
        <h1>机构介绍</h1>
        <a class="green fr more" href="org-detail-desc.html">查看更多  >  </a>
    </div>                           <!--desc是机构描述字段-->
    <div class="cont">&nbsp; &nbsp;{{ course_org.desc }}<a href="/company/desc/22/"><span class="green">[查看更多]</span></a></div>
</div>

机构课程页、机构介绍页、机构讲师页

class OrgCourseView(View):  # 机构课程页
    """
    机构课程页
    """
    def get(self, request, org_id):
        current_page = 'course'
        course_org = CourseOrg.objects.get(id=int(org_id))
        # 获取某机构所有课程的方法
        all_courses = course_org.course_set.all()
        return render(request, 'org-detail-course.html', {
            'all_courses': all_courses,
            'course_org': course_org,  # 获取对应id的机构,机构内有logo、机构描述desc等字段。
            'current_page': current_page,
        })


class OrgDescView(View):  # 机构介绍页
    """
    机构介绍页
    """
    def get(self, request, org_id):
        current_page = 'desc'
        course_org = CourseOrg.objects.get(id=int(org_id))
        return render(request, 'org-detail-desc.html', {
            'course_org': course_org,  # 获取对应id的机构,机构内有logo、机构描述desc等字段。
            'current_page': current_page,
        })


class OrgTeacherView(View):  # 机构讲师页
    """
    机构讲师页
    """
    def get(self, request, org_id):
        current_page = 'teacher'
        course_org = CourseOrg.objects.get(id=int(org_id))
        # 获取某机构所有讲师的方法
        all_teachers = course_org.teacher_set.all()
        return render(request, 'org-detail-teachers.html', {
            'all_teachers': all_teachers,
            'course_org': course_org,  # 获取对应id的机构,机构内有logo、机构描述desc等字段。
            'current_page': current_page,
        })

url

re_path('^course/(?P<org_id>\d+)/$', views.OrgCourseView.as_view(), name='org_course'),
re_path('^desc/(?P<org_id>\d+)/$', views.OrgDescView.as_view(), name='org_desc'),
re_path('^teacher/(?P<org_id>\d+)/$', views.OrgTeacherView.as_view(), name='org_teacher'),

课程机构收藏功能  -- 也是一个异步方法,由ajax来完成

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值