第7章 课程机构功能实现

慕课网《强力django+杀手级xadmin 打造上线标准的在线教育平台》 学习笔记


本章主要内容:

  • 完成课程机构的相关功能
  • 本章会开始django的templates模板继承机制实现模板的重用。
  • 本章包括分页、筛选、收藏等功能, 会讲到如何通过modelform对表单进行验证和保存。

  • 分析页面
    这里写图片描述

Django模板操作

The Django Book 2.0 中文版 第四章 模板

  • 包含与继承

后台添加一些数据

这里写图片描述

  • 图片路径的配置

列表展示

  • 取出所有的机构
class OrgView(View):
    """
    课程机构列表功能
    """
    def get(self, request):
        #课程机构
        all_orgs = CourseOrg.objects.all()  
        return render(request, "org-list.html", {
            "all_orgs":orgs
        })

列表展示

<div class="cont">
    <a href="?ct={{ category }}"><span class="{% ifequal city_id '' %}active2{% endifequal %}">全部</span></a>
        {% for city in all_citys %}
            <a href="?city={{ city.id }}&ct={{ category }}"><span class="{% ifequal city_id city.id|stringformat:"i" %}active2{% endifequal %}">{{ city.name }}</span></a>
        {% endfor %}
</div>

分页

django-pure-pagination provides advanced pagination features and is fully compatible with existing code based on Django’s core pagination module. (aka no need to rewrite code!)

这里写图片描述

  • 安装及配置略

  • 后台分页

#课程机构
all_orgs = CourseOrg.objects.all()

# 对课程机构进行分页
try:
    page = request.GET.get('page', 1)
except PageNotAnInteger:
    page = 1

p = Paginator(all_orgs, 5, request=request)  # 每页5个

orgs = p.page(page)
  • 前台分页显示
<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 %}
            {% else %}
                <li class="none"><a href="">...</a></li>
            {% endif %}
        {% endfor %}

        {% if all_orgs.has_next %}
            <li class="long"><a href="?{{ all_orgs.next_page_number.querystring }}">下一页</a></li>
        {% endif %}
    </ul>
</div>

这里写图片描述


筛选

这里写图片描述

  • 分别传机构类别、所在地区、排序sort的参数,参数存在则过滤或排序,最后把参数传回页面
class OrgView(View):
    """
    课程机构列表功能
    """
    def get(self, request):
        #课程机构
        all_orgs = CourseOrg.objects.all()
        # 机构排名,按点击数排序,取前3
        hot_orgs = all_orgs.order_by("-click_nums")[:3]

        #城市
        all_citys = CityDict.objects.all()

        #机构搜索
        search_keywords = request.GET.get('keywords', "")
        if search_keywords:
            all_orgs = all_orgs.filter(Q(name__icontains=search_keywords)|Q(desc__icontains=search_keywords))

        #取出筛选城市
        city_id = request.GET.get('city', "")
        if city_id:
            all_orgs = all_orgs.filter(city_id=int(city_id))

        #类别筛选
        category = request.GET.get('ct', "")
        if category:
            all_orgs = all_orgs.filter(category=category)\

        sort = request.GET.get('sort', "")
        if sort:
            if sort == "students":
                all_orgs = all_orgs.order_by("-students")
            elif sort == "courses":
                all_orgs = all_orgs.order_by("-course_nums")

        # 最后才计数
        org_nums = all_orgs.count()


        #对课程机构进行分页
        try:
            page = request.GET.get('page', 1)
        except PageNotAnInteger:
            page = 1

        p = Paginator(all_orgs, 5, request=request)

        orgs = p.page(page)
        return render(request, "org-list.html", {
            "all_orgs":orgs,
            "all_citys":all_citys,
            "org_nums": org_nums,
            "city_id": city_id,
            "category": category,
            "hot_orgs": hot_orgs,
            "sort": sort
        })

前台页面

  • 筛选机构类别
    注意:同时要把城市的参数 &city={{ city_id }} 带上去
<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 category 'pxjg' %}active2{% endifequal %}">培训机构</span></a>

            <a href="?ct=gx&city={{ city_id }}"><span class="{% ifequal category 'gx' %}active2{% endifequal %}">高校</span></a>

            <a href="?ct=gr&city={{ city_id }}"><span class="{% ifequal category 'gr' %}active2{% endifequal %}">个人</span></a>

    </div>
</li>
  • 筛选所在地区
    注意:此处也要把机构类别 &ct={{ category }} 带上去
<li>
    <h2>所在地区</h2>
    <div class="more">更多</div>
    <div class="cont">
        <a href="?ct={{ category }}"><span class="{% ifequal city_id '' %}active2{% endifequal %}">全部</span></a>
            {% for city in all_citys %}
                <a href="?city={{ city.id }}&ct={{ category }}"><span class="{% ifequal city_id city.id|stringformat:"i" %}active2{% endifequal %}">{{ city.name }}</span></a>
            {% endfor %}
    </div>
</li>
  • 结果数量
<div class="all"><span class="key">{{ org_nums }}</span></div>
  • 排序
    此处要同时把上面两个参数 ?ct={{ category }}&city={{ city_id }} 带上去
<div class="head">
    <ul class="tab_header">
        <li class="{% if sort == '' %}active{% endif %}"><a href="?ct={{ category }}&city={{ city_id }}">全部</a> </li>
        <li class="{% if sort == 'students' %}active{% endif %}"><a href="?sort=students&ct={{ category }}&city={{ city_id }}">学习人数 &#8595;</a></li>
        <li class="{% if sort == 'courses' %}active{% endif %}"><a href="?sort=courses&ct={{ category }}&city={{ city_id }}">课程数 &#8595;</a></li>
    </ul>
</div>
  • 机构排名
<div class="right companyrank layout">
    <div class="head">授课机构排名</div>

    {% for curent_org in hot_orgs %}
        <dl class="des">
            <dt class="num fl">{{ forloop.counter }}</dt>
            <dd>
                <a href="/company/2/"><h1>{{ curent_org.name }}</h1></a>
                <p>{{ curent_org.address }}</p>
            </dd>
        </dl>
    {% endfor %}
</div>

使用ModelForm提交‘我要学习’表单

The Django Book 2.0–中文版 第7章 表单

  • 当表单和model很相似的时候可以用ModelForm从指定的Model生成
  • 可以指定只要model的哪些字段
  • 可以扩展新的字段
  • 可以直接保存model

验证

  • 可以在表单中定义一些验证字段的函数,以clean_*开头,表示检查哪一个字段的合法性,modelform在检查合法性时会自动调用该方法
  • 在该方法中通过 self.cleaned_data 可以获取表单中的数据
class UserAskForm(forms.ModelForm):
    # 新扩展的字段
    # newArgs = forms.CharField(required=True, min_length=5)
    class Meta:
        model = UserAsk    # 指定从那个model生成
        # 指定只要Model中的哪些字段
        fields = ['name', 'mobile', 'course_name'] 

    def clean_mobile(self):
        """
        验证手机号码是否合法
        """
        mobile = self.cleaned_data['mobile']
        REGEX_MOBILE = "^1[358]\d{9}$|^147\d{8}$|^176\d{8}$"
        p = re.compile(REGEX_MOBILE)  
        if p.match(mobile):  
            return mobile
        else:
            raise forms.ValidationError(u"手机号码非法", code="mobile_invalid")

分发 url

  • 防止项目的urls.py臃肿
  • 命名空间可减少重名

这里写图片描述

这里写图片描述

  • 使用
<a href="{% url 'org:org_home' course_org.id %}">

提交表单

  • ModelForm可以直接保存save(),不需要转换成model
  • HttpResponse 返回 json
    注意:此处是ajax提交
class AddUserAskView(View):
    """
    用户添加咨询
    """
    def post(self, request):
        userask_form = UserAskForm(request.POST)
        if userask_form.is_valid():
            user_ask = userask_form.save(commit=True) # 关键是这里
            return HttpResponse('{"status":"success"}', content_type='application/json')
        else:
            return HttpResponse('{"status":"fail", "msg":"添加出错"}', content_type='application/json')
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值