1. 程式人生 > >Django+xadmin打造在線教育平臺(四)

Django+xadmin打造在線教育平臺(四)

技術 hot dfa index lin height 東方 邏輯 then

Django+xadmin打造在線教育平臺(四)

代碼

github下載

七、授課機構功能

7.1.模板繼承

(1)創建母板

把org-list.html拷貝到templates目錄下,新建base.html,剪切org-list.html內容到裏面

技術分享圖片

技術分享圖片

再修改一下靜態文件的地址(css、就是、image和media)

(2)機構首頁路由

from organization.views import OrgView

path(‘org_list/‘,OrgView.as_view(),name = ‘org_list‘),

(3)機構views

class OrgView(View):
    ‘‘‘課程機構‘‘‘
    def get(self,request):
        return render(request,‘org-list.html‘)

(4)org-list.html繼承base

技術分享圖片
{#templates/org-list.html#}

{% extends ‘base.html‘ %}

{% block title %}
    課程機構列表
{% endblock %}
技術分享圖片

訪問:http://127.0.0.1:8000/org_list/ 可以看到org_list頁面

技術分享圖片

(5)修改base模板

把base中custom_bread和content兩個block的內容剪切到org-list.html裏面

base.html

技術分享圖片

org-list.html

技術分享圖片

7.2.添加城市和課程機構

(1)進xadmin後臺添加城市

技術分享圖片

這裏機構是靜態固定不變的,所在地區是動態的,從數據庫中獲取得到的

技術分享圖片

(2)修改機構的models,添加一個機構類別字段

organization/models.py:

技術分享圖片
class CourseOrg(models.Model):
    ORG_CHOICES = (
        ("pxjg", u"培訓機構"),
        ("gx", u"高校"),
        ("gr", u"個人"),
    )

#添加字段
 category = models.CharField(max_length=20, choices=ORG_CHOICES, verbose_name=u"機構類別", default="pxjg")
技術分享圖片 技術分享圖片 全部代碼

添加後makemigrations-->>migrate

(3)添加機構

添加機構信息的時候要上傳機構的圖片

在項目目錄下面新建一個目錄“media”,用來存放上傳的圖片

setting中要配置我們把文件存放在哪個根目錄之下

#settings.py

# 設置上傳文件的路徑
MEDIA_URL = ‘/media/‘
MEDIA_ROOT = os.path.join(BASE_DIR,‘media‘)   #指定根目錄

會跟upload裏面拼接完整的路徑

“/media/org/2018/月份/圖片名字”

技術分享圖片

然後在後臺添加十個機構

技術分享圖片

7.3.顯示課程機構和城市

(1)寫視圖函數organization/views.py

技術分享圖片
class OrgView(View):
    ‘‘‘課程機構‘‘‘
    def get(self,request):
        # 取出所有課程機構
        all_orgs = CourseOrg.objects.all()
        org_onums = all_orgs.count()
        # 取出所有城市
        all_citys = CityDict.objects.all()
        return render(request, "org-list.html", {
            "all_orgs": all_orgs,
            "all_citys": all_citys,
            ‘org_onums‘:org_onums,
        })
技術分享圖片

(2)修改org-list.html

顯示機構總共數量

技術分享圖片

顯示城市

技術分享圖片

顯示機構

技術分享圖片

技術分享圖片

然後還要做下面的設置

如何將image Field轉換成圖片地址

數據庫中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

技術分享圖片
from django.views.static import serve
from MxOnline.settings import MEDIA_ROOT


# 處理圖片顯示的url,使用Django自帶serve,傳入參數告訴它去哪個路徑找,我們有配置好的路徑MEDIAROOT
re_path(r‘^media/(?P<path>.*)‘, serve, {"document_root": MEDIA_ROOT })
技術分享圖片

四個地方

技術分享圖片

7.4.分頁功能

使用 分頁神器 django-pure-pagination 分頁,github上面有介紹使用方法

(1)安裝

pip install django-pure-pagination

(2)settings裏面添加

INSTALLED_APPS = (
    ...
    ‘pure_pagination‘,
)

(3)views中使用方法

技術分享圖片
class OrgView(View):
    ‘‘‘課程機構‘‘‘

    def get(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)
        except PageNotAnInteger:
            page = 1
        # 這裏指從allorg中取五個出來,每頁顯示5個
        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,
        })
技術分享圖片

(4)修改org-list.html

這裏變成 "all_orgs.object_list"

技術分享圖片

分頁功能

技術分享圖片
<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>
技術分享圖片

改成每頁顯示2個列表,如下:

技術分享圖片

7.5.列表篩選功能

(1)城市列表篩選

技術分享圖片

  • 點城市,篩選出對應的課程機構
  • 默認“全部”是‘active’狀態(綠色),如果點了某個城市,應該城市是‘active’狀態
  • 當用戶點擊city時,應該把city的id傳到後臺,然後後臺在傳到模板中,是的可以知道哪個城市被選中,然後加上‘’active‘’

後臺處理city篩選

技術分享圖片
class OrgView(View):
    ‘‘‘課程機構‘‘‘

    def get(self, request):
        # 所有課程機構
        all_orgs = CourseOrg.objects.all()
        # 有多少家機構
        org_nums = all_orgs.count()
        # 所有城市
        all_citys = CityDict.objects.all()

        city_id = request.GET.get(‘city‘,‘‘)
        if city_id:
            all_orgs = all_orgs.filter(city_id=int(city_id))

        # 對課程機構進行分頁
        # 嘗試獲取前臺get請求傳遞過來的page參數
        # 如果是不合法的配置參數默認返回第一頁
        try:
            page = request.GET.get(‘page‘, 1)
        except PageNotAnInteger:
            page = 1
        # 這裏指從allorg中取五個出來,每頁顯示5個
        p = Paginator(all_orgs, 2, 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,
        })
技術分享圖片

前端頁面

技術分享圖片
<h2>所在地區</h2>
    <div class="more">更多</div>
    <div class="cont">
        <a href="?ct="><span class="{% ifequal city_id ‘‘ %}active2{% endifequal %}">全部</span></a>
        {% for city in all_citys %}
            <a href="?city={{ city.id }}"><span class="{% ifequal city.id|stringformat:‘i‘ city_id %}active2{% endifequal %}">{{ city.name }}</span></a>
        {% endfor %}
    </div>
技術分享圖片

因為city.id是一個int類型,要轉換成字符串,再作比較。

{% ifequal city_id ‘‘ %} 如果為空,說明沒有city選中,則“全部”是“active”

(2)類別篩選

技術分享圖片

後臺處理

技術分享圖片
     # 類別篩選
        category = request.GET.get(‘ct‘,‘‘)
        if category:
            all_orgs = all_orgs.filter(category=category)

        # 有多少家機構
        org_nums = all_orgs.count()
技術分享圖片

把org_numsf放到後面,先篩選在統計數量

模板中

技術分享圖片
<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>
技術分享圖片 技術分享圖片
<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>
技術分享圖片

進行城市與分類的聯動:

  • 當選擇全部類別的時候,就只通過當前城市id。
  • 當選擇全部城市的時候,就只通過當前目錄id。
  • 當兩者都選的時候使用&連接。

技術分享圖片

(3)課程機構排名篩選

後臺處理

按點擊量排名,只取前三個

# 熱門課程機構排名
hot_orgs = all_orgs.order_by(‘-click_nums‘)[:3]

模板中

技術分享圖片
<div class="right companyrank layout">
    <div class="head">授課機構排名</div>
    {% for curent_org in hot_orgs %}
    <dl class="des">
        <dt class="num fl">{{ foorloop.counter }}</dt>
        <dd>
            <a href="/company/2/"><h1>{{ curent_org.name }}</h1></a>
            <p>{{ curent_org.address }}</p>
        </dd>
    </dl>
    {% endfor %}
</div>
技術分享圖片

循環時內置變量forloop.counter取當前循環到第幾次

技術分享圖片

(4)學習人數和課程的篩選

技術分享圖片

在models中添加學習人數和課程數兩個字段

students = models.IntegerField("學習人數",default=0)
course_nums = models.IntegerField("課程數",default=0)
技術分享圖片 CourseOrg

migrate到數據庫

後臺處理

技術分享圖片
# 學習人數和課程數篩選
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")
技術分享圖片

技術分享圖片 OrgView

前端

技術分享圖片
 <div class="head">
        <ul class="tab_header">
            <li class="{% if sort == ‘‘ %}active{% endif %}"><a href="?sort=students&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>
技術分享圖片

技術分享圖片

7.6.提交我要學習咨詢

(1)用ModelForm來實現

在organazition目錄下創建forms.py文件

技術分享圖片

技術分享圖片
# organization/forms.py

from django import forms
from operation.models import UserAsk


class UserAskForm(forms.Form):
    ‘‘‘我要咨詢‘‘‘
    class Meta:
        model = UserAsk
        fields = [‘name‘,‘mobile‘,‘course_name‘]
技術分享圖片

(2)include路由分發

技術分享圖片 MxOnline/urls.py

刪掉org_list的那個路由,改成include

path("org/", include(‘organization.urls‘, namespace="org")),

使用命名空間防止重復

然後在organization/urls.py中添加

技術分享圖片
# organization/urls.py

from organization.views import OrgView

from django.urls import path,re_path

# 要寫上app的名字
app_name = "organization"

urlpatterns = [
    path(‘list/‘,OrgView.as_view(),name=‘org_list‘),
]
技術分享圖片

html中使用命名空間的方式:

修改base.html中“課程機構的鏈接”

<li class="active" ><a href="{% url ‘org:org_list‘ %}">授課機構</a></li>

(3)視圖函數

技術分享圖片
from django.http import HttpResponse
from .forms import UserAskForm


class AddUserAskView(View):
    """
    用戶添加咨詢
    """
    def post(self, request):
        userask_form = UserAskForm(request.POST)
        if userask_form.is_valid():
            user_ask = userask_form.save(commit=True)
            # 如果保存成功,返回json字符串,後面content type是告訴瀏覽器返回的數據類型
            return HttpResponse(‘{"status":"success"}‘, content_type=‘application/json‘)
        else:
            # 如果保存失敗,返回json字符串,並將form的報錯信息通過msg傳遞到前端
            return HttpResponse(‘{"status":"fail", "msg":"添加出錯"}‘, content_type=‘application/json‘)
技術分享圖片 技術分享圖片 views.py

這裏要用到Ajax提交,不會對頁面整體刷新,應該給前端返回一個Json數據

HttpResponse可以指定傳遞到前端的數據類型

(4)配置url

技術分享圖片
# organization/urls.py

from organization.views import OrgView,AddUserAskView

from django.urls import path,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.py

import re
from django import forms
from operation.models import UserAsk


class UserAskForm(forms.ModelForm):

    class Meta:
        model = UserAsk
        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")
技術分享圖片

(6)模板中使用Ajax方式提交

org-list.html

技術分享圖片
<div class="right companyright">
    <div class="head">我要學習</div>
    <form class="rightform" id="jsStayForm">
        <div>
            <img src="{% static ‘images/rightform1.png‘ %}"/>
            <input type="text" name="name" id="companyName" placeholder="名字" maxlength="25"/>
        </div>
        <div>
            <img src="{% static ‘images/rightform2.png‘ %}"/>
            <input type="text" name="mobile" id="companyMobile" placeholder="聯系電話"/>
        </div>
        <div>
            <img src="{% static ‘images/rightform3.png‘ %}"/>
            <input type="text" name="course_name" id="companyAddress" placeholder="課程名" maxlength="50"/>
        </div>
        <p class="error company-tips" id="jsCompanyTips"></p>
        <input class="btn" type="text" id="jsStayBtn" value="立即咨詢 >"/>
        {% csrf_token %}
    </form>
</div>
技術分享圖片 技術分享圖片
<script>
    $(function () {
        $(‘#jsStayBtn‘).on(‘click‘, function () {
            $.ajax({
                cache: false,
                type: "POST",
                url: "{% url "org:add_ask" %}",
                data: $(‘#jsStayForm‘).serialize(),
                async: true,
                success: function (data) {
                    if (data.status == ‘success‘) {
                        $(‘#jsStayForm‘)[0].reset();
                        alert("提交成功")
                    } else if (data.status == ‘fail‘) {
                        $(‘#jsCompanyTips‘).html(data.msg)
                    }
                },
            });
        });
    })
</script>
技術分享圖片 技術分享圖片 org-list.html全部代碼

提交數據不合法時

技術分享圖片

合法時,提示成功信息,數據保存到數據庫

技術分享圖片

7.7.機構首頁

(1)給courses添加一個外鍵

from organization.models import CourseOrg

course_org = models.ForeignKey(CourseOrg, on_delete=models.CASCADE, verbose_name="所屬機構", null=True, blank=True)
技術分享圖片 全部代碼

在後臺添加課程和講師

(2)模板

把課程機構頁面的四個文件拷貝到templates目錄下

技術分享圖片

新建一個模板,命名為“org_base.html”,復制org-detail-homepage.html的內容到裏面

添加block,修改靜態文件路徑

技術分享圖片

技術分享圖片

技術分享圖片

技術分享圖片 org_base.html

(3)org-detail-home.html繼承模板

把org_base中的三個“right”剪切到home裏面

技術分享圖片

(4)home頁面的url

from .views import OrgHomeView

re_path(‘home/(?P<org_id>\d+)/‘, OrgHomeView.as_view(), name="org_home"),

(5)後端邏輯處理

技術分享圖片
class OrgHomeView(View):
    ‘‘‘機構首頁‘‘‘

    def get(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]
        return render(request,‘org-detail-homepage.html‘,{
            ‘course_org‘:course_org,
            ‘all_courses‘:all_courses,
            ‘all_teacher‘:all_teacher,
        })
技術分享圖片

(6)顯示全部課程

技術分享圖片
<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.name }}</span>
                 <span class="star fr  notlogin
                    " data-favid="13"  data-fav-type="4">
                    {{ course.fav_nums }}
                </span>
            </div>
        </div>
        {% endfor %}
</div>
技術分享圖片

在org-list.html中修改鏈接,點擊機構,跳到對應機構主頁

技術分享圖片

(6)修改org-base.html

技術分享圖片

技術分享圖片

(7)為teacher添加一個圖形字段

image = models.ImageField(
    default= ‘‘,
    upload_to="teacher/%Y/%m",
    verbose_name="頭像",
    max_length=100)

(8)顯示機構教師

技術分享圖片

(9)顯示機構詳情

技術分享圖片

機構 首頁:

技術分享圖片

技術分享圖片

7.8.機構課程

(1)模板文件

把org-detail-course.html中不同的地方(right)取出來

技術分享圖片

(2)添加url

re_path(‘course/(?P<org_id>\d+)/‘, OrgCourseView.as_view(), name="org_course"),

(3)views.py

技術分享圖片
class OrgCourseView(View):
    """
   機構課程列表頁
    """
    def get(self, request, org_id):
        # 根據id取到課程機構
        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,
        })
技術分享圖片

(4)修改org-base.html中left的鏈接

技術分享圖片

(5)顯示機構課程,修改org-detail-course.html

技術分享圖片
<div class="brief group_list">
{% for course in all_courses %}
    <div class="module1_5 box">
        <a class="comp-img-box" href="course-detail.html">

            <img width="214" height="195" 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.name }}</span>
            <span class="star fr  notlogin
                " data-favid="13" data-fav-type="4">
                {{ course.fav_nums }}
            </span>
        </div>
    </div>
{% endfor %}
技術分享圖片

點“機構課程”,看有哪些課程

技術分享圖片

(6)左側“active”狀態修改

因為現在沒有值能判斷當前是哪個頁面。所以在後臺傳個current page參數

修改org_base.html

技術分享圖片
<div class="left">
    <ul>
        <li class="{% ifequal current_page ‘home‘ %}active2{% endifequal %}"><a href="{% url ‘org:org_home‘ course_org.id %}">機構首頁</a></li>
        <li class="{% ifequal current_page ‘course‘ %}active2{% endifequal %}"><a href="{% url ‘org:org_course‘ course_org.id %}">機構課程</a></li>
        <li class="{% ifequal current_page ‘desc‘ %}active2{% endifequal %}"><a href="org-detail-desc.html">機構介紹</a></li>
        <li class="{% ifequal current_page ‘teacher‘ %}active2{% endifequal %}"><a href="org-detail-teachers.html">機構講師</a></li>
    </ul>
</div>
技術分享圖片

修改views,傳個current_page參數到前端,可以知道當前是哪個被激活狀態

技術分享圖片
class OrgHomeView(View):
    ‘‘‘機構首頁‘‘‘

    def get(self,request,org_id):
        current_page = ‘home‘
        # 根據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]
        return render(request,‘org-detail-homepage.html‘,{
            ‘course_org‘:course_org,
            ‘all_courses‘:all_courses,
            ‘all_teacher‘:all_teacher,
            ‘current_page‘:current_page,
        })
技術分享圖片 技術分享圖片
class OrgCourseView(View):
    """
   機構課程列表頁
    """
    def get(self, request, org_id):
        current_page = ‘course‘
        # 根據id取到課程機構
        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,
            ‘current_page‘:current_page,
        })
技術分享圖片

技術分享圖片

7.9.機構介紹

(1)url

re_path(‘desc/(?P<org_id>\d+)/‘, OrgDescView.as_view(), name="org_desc"),

技術分享圖片

(2)views

技術分享圖片
class OrgDescView(View):
    ‘‘‘機構介紹頁‘‘‘
    def get(self, request, org_id):
        current_page = ‘desc‘
        # 根據id取到課程機構
        course_org = CourseOrg.objects.get(id= int(org_id))
        return render(request, ‘org-detail-desc.html‘,{
            ‘course_org‘: course_org,
            ‘current_page‘:current_page,
        })
技術分享圖片

7.10.機構講師

(1)url

re_path(‘teacher/(?P<org_id>\d+)/‘, OrgTeacherView.as_view(), name="org_teacher"),

(2)views

技術分享圖片
class OrgTeacherView(View):
    """
   機構教師頁
    """
    def get(self, request, org_id):
        current_page = ‘teacher‘
        course_org = CourseOrg.objects.get(id= int(org_id))
        all_teacher = course_org.teacher_set.all()

        return render(request, ‘org-detail-teachers.html‘,{
           ‘all_teacher‘:all_teacher,
            ‘course_org‘: course_org,
            ‘current_page‘:current_page,
        })
技術分享圖片

(3)org-detail-teachers.html

技術分享圖片
{% extends ‘org_base.html‘ %}
{% load staticfiles %}

<title>{% block title %}機構教師頁--新東方{% endblock %}</title>

{% block right_form %}
 <div class="right companycenter layout" >
        <div class="head">
            <h1>機構講師</h1>
        </div>
        <div class="messagelist">
            <div class=" butler_list butler-fav-box">
                {% for teacher in all_teacher %}
                <dl class="des users">
                    <dt>
                        <a href="">
                        <img width="100" height="100" class="scrollLoading" data-url="{{ MEDIA_URL }}{{ teacher.image }}" src="{{ MEDIA_URL }}{{ teacher.image }}"/>
                        </a>
                    </dt>
                    <dd>
                        <h1>
                            <a href="">
                            {{ teacher.name }}<span class="key">已認證</span>
                            </a>
                        </h1>
                        <ul class="cont clearfix">
                            <li class="time">工作年限:<span>{{ teacher.work_years }}</span></li>
                            <li class="c7">課程數:<span>3</span></li>
                        </ul>
                    </dd>
                </dl>
                {% endfor %}
            </div>
        </div>
    </div>
{% endblock %}
技術分享圖片

(4)org-bae.html中left

技術分享圖片
<ul>
   <li class="{% ifequal current_page ‘home‘ %}active2{% endifequal %}"><a href="{% url ‘org:org_home‘ course_org.id %}">機構首頁</a></li>
   <li class="{% ifequal current_page ‘course‘ %}active2{% endifequal %}"><a href="{% url ‘org:org_course‘ course_org.id %}">機構課程</a></li>
   <li class="{% ifequal current_page ‘desc‘ %}active2{% endifequal %}"><a href="{% url ‘org:org_desc‘ course_org.id %}">機構介紹</a></li>
   <li class="{% ifequal current_page ‘teacher‘ %}active2{% endifequal %}"><a href="{% url ‘org:org_teacher‘ course_org.id %}">機構講師</a></li>
</ul>
技術分享圖片

(5)修改面包屑,點機構課程應該顯示機構課程

技術分享圖片

base.html

技術分享圖片

然後分別在其它四個頁面中重載page_path

技術分享圖片

技術分享圖片

其它三個方法一樣

7.11.課程機構收藏功能

技術分享圖片

(1)url

path(‘add_fav/‘, AddFavView.as_view(), name="add_fav"),
技術分享圖片 organization/urls.py 技術分享圖片 MxOnline/urls.py

(2)後臺處理

技術分享圖片
class AddFavView(View):
    """
    用戶收藏和取消收藏
    """
    def post(self, request):
        fav_id = request.POST.get(‘fav_id‘, 0)         # 防止後邊int(fav_id)時出錯
        fav_type = request.POST.get(‘fav_type‘, 0)     # 防止int(fav_type)出錯

        if not request.user.is_authenticated:
            # 未登錄時返回json提示未登錄,跳轉到登錄頁面是在ajax中做的
            return HttpResponse(‘{"status":"fail", "msg":"用戶未登錄"}‘, content_type=‘application/json‘)

        exist_record = UserFavorite.objects.filter(user=request.user, fav_id=int(fav_id), fav_type=int(fav_type))
        if exist_record:
            # 如果記錄已經存在,表示用戶取消收藏
            exist_record.delete()
            return HttpResponse(‘{"status":"fail", "msg":"已取消收藏"}‘, content_type=‘application/json‘)
        else:
            user_fav = UserFavorite()
            if int(fav_id) > 0 and int(fav_type) > 0:
                user_fav.user = request.user
                user_fav.fav_id = int(fav_id)
                user_fav.fav_type = int(fav_type)
                user_fav.save()
                return HttpResponse(‘{"status":"success", "msg":"已收藏"}‘, content_type=‘application/json‘)
            else:
                return HttpResponse(‘{"status":"fail", "msg":"收藏出錯"}‘, content_type=‘application/json‘)
技術分享圖片

(3)前端Ajax

Ajax放在org_base.html裏面

技術分享圖片
<script type="text/javascript">
    //收藏分享
//收藏分享
function add_fav(current_elem, fav_id, fav_type){
    $.ajax({
        cache: false,
        type: "POST",
        url:"{% url ‘org:add_fav‘ %}",
        data:{‘fav_id‘:fav_id, ‘fav_type‘:fav_type},
        async: true,
        beforeSend:function(xhr, settings){
            xhr.setRequestHeader("X-CSRFToken", "{{ csrf_token }}");
        },
        success: function(data) {
            if(data.status == ‘fail‘){
                if(data.msg == ‘用戶未登錄‘){
                    window.location.href="/login/";
                }else{
                    alert(data.msg)
                }

            }else if(data.status == ‘success‘){
                current_elem.text(data.msg)
            }
        },
    });
}

$(‘.collectionbtn‘).on(‘click‘, function(){
    add_fav($(this), {{ course_org.id }}, 2);
});
技術分享圖片

訪問頁面點右上角的“收藏”,可以發現正常工作了

技術分享圖片

可以在數據庫中看到用戶的收藏

技術分享圖片

再點“收藏”,會提示“已取消收藏”

技術分享圖片

(4)但是還有個問題就是 ,刷新頁面後,“已收藏”就變成“收藏”,是因為在返回頁面的時候,沒有判斷收藏狀態

所有要在views裏面加個判斷

        # 判斷收藏狀態
        has_fav = False
        if request.user.is_authenticated:
            if UserFavorite.objects.filter(user=request.user, fav_id=course_org.id, fav_type=2):
                has_fav = True

四個頁面都加上這個判斷

技術分享圖片 organization/views.py

(5)在org_base.html添加判斷

技術分享圖片

(6)修改右上角登錄和註冊

把index.html頁面中的登錄、註冊判斷放到org_base裏面

技術分享圖片

Django+xadmin打造在線教育平臺(四)