欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Django+xadmin打造在线教育平台(四)

程序员文章站 2022-09-26 15:08:13
七、授课机构功能 7.1.模板继承 (1)创建母板 把org-list.html拷贝到templates目录下,新建base.html,剪切org-list.html内容到里面 再修改一下静态文件的地址(css、就是、image和media) (2)机构首页路由 (3)机构views (4)org- ......

七、授课机构功能

7.1.模板继承

(1)创建母板

把org-list.html拷贝到templates目录下,新建base.html,剪切org-list.html内容到里面

Django+xadmin打造在线教育平台(四)

Django+xadmin打造在线教育平台(四)

再修改一下静态文件的地址(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页面

Django+xadmin打造在线教育平台(四)

 

(5)修改base模板

把base中custom_bread和content两个block的内容剪切到org-list.html里面

base.html

Django+xadmin打造在线教育平台(四)

org-list.html

Django+xadmin打造在线教育平台(四)

7.2.添加城市和课程机构

 (1)进xadmin后台添加城市

Django+xadmin打造在线教育平台(四)

 这里机构是静态固定不变的,所在地区是动态的,从数据库中获取得到的

Django+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")
Django+xadmin打造在线教育平台(四)
class CourseOrg(models.Model):
    ORG_CHOICES = (
        ("pxjg", u"培训机构"),
        ("gx", u"高校"),
        ("gr", u"个人"),
    )
    name = models.CharField('机构名称',max_length=50)
    desc = models.TextField('机构描述')
    category = models.CharField(max_length=20, choices=ORG_CHOICES, verbose_name=u"机构类别", default="pxjg")
    click_nums = models.IntegerField('点击数',default=0)
    fav_nums = models.IntegerField('收藏数',default=0)
    image = models.ImageField('logo',upload_to='org/%Y%m',max_length=100)
    address = models.CharField('机构地址',max_length=150,)
    city = models.ForeignKey(CityDict,verbose_name='所在城市',on_delete=models.CASCADE)
    add_time = models.DateTimeField(default=datetime.now)

    class Meta:
        verbose_name = '课程机构'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name
全部代码

添加后makemigrations-->>migrate

(3)添加机构

添加机构信息的时候要上传机构的图片

在项目目录下面新建一个目录“media”,用来存放上传的图片

setting中要配置我们把文件存放在哪个根目录之下

#settings.py

# 设置上传文件的路径
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR,'media')   #指定根目录

会跟upload里面拼接完整的路径

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

Django+xadmin打造在线教育平台(四)

然后在后台添加十个机构

Django+xadmin打造在线教育平台(四)

 

 

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

显示机构总共数量

Django+xadmin打造在线教育平台(四)

显示城市

Django+xadmin打造在线教育平台(四)

显示机构

Django+xadmin打造在线教育平台(四)

Django+xadmin打造在线教育平台(四)

然后还要做下面的设置

如何将image Field转换成图片地址

 数据库中image以字符串格式保存的,是相对路径,直接取是取不出来的,必须补全路径

Django+xadmin打造在线教育平台(四)

 

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 })

四个地方

Django+xadmin打造在线教育平台(四)

 

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"

Django+xadmin打造在线教育平台(四)

分页功能

<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个列表,如下:

Django+xadmin打造在线教育平台(四)

 

7.5.列表筛选功能

(1)城市列表筛选

Django+xadmin打造在线教育平台(四)

  • 点城市,筛选出对应的课程机构
  • 默认“全部”是‘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)类别筛选

Django+xadmin打造在线教育平台(四)

 

 后台处理

     # 类别筛选
        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。
  • 当两者都选的时候使用&连接。

Django+xadmin打造在线教育平台(四)

 

 (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取当前循环到第几次

 Django+xadmin打造在线教育平台(四)

 

 (4)学习人数和课程的筛选

Django+xadmin打造在线教育平台(四)

在models中添加学习人数和课程数两个字段

students = models.IntegerField("学习人数",default=0)
course_nums = models.IntegerField("课程数",default=0)
Django+xadmin打造在线教育平台(四)
class CourseOrg(models.Model):
    ORG_CHOICES = (
        ("pxjg", u"培训机构"),
        ("gx", u"高校"),
        ("gr", u"个人"),
    )
    name = models.CharField('机构名称',max_length=50)
    desc = models.TextField('机构描述')
    category = models.CharField(max_length=20, choices=ORG_CHOICES, verbose_name=u"机构类别", default="pxjg")
    click_nums = models.IntegerField('点击数',default=0)
    fav_nums = models.IntegerField('收藏数',default=0)
    students = models.IntegerField("学习人数",default=0)
    course_nums = models.IntegerField("课程数",default=0)
    image = models.ImageField('logo',upload_to='org/%Y/%m',max_length=100)
    address = models.CharField('机构地址',max_length=150,)
    city = models.ForeignKey(CityDict,verbose_name='所在城市',on_delete=models.CASCADE)
    add_time = models.DateTimeField(default=datetime.now)

    class Meta:
        verbose_name = '课程机构'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name
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")

 

Django+xadmin打造在线教育平台(四)
class OrgView(View):
    '''课程机构'''

    def get(self, request):
        # 所有课程机构
        all_orgs = CourseOrg.objects.all()

        # 所有城市
        all_citys = CityDict.objects.all()
        # 城市筛选
        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)

        # 热门课程机构排名
        hot_orgs = all_orgs.order_by('-click_nums')[:3]
        # 学习人数和课程数筛选
        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()
        # 对课程机构进行分页
        # 尝试获取前台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,
            "category": category,
            'hot_orgs':hot_orgs,
            'sort':sort,
        })
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>

 

Django+xadmin打造在线教育平台(四)

 

7.6.提交我要学习咨询

(1)用ModelForm来实现

在organazition目录下创建forms.py文件

Django+xadmin打造在线教育平台(四)

# 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路由分发

Django+xadmin打造在线教育平台(四)
# MxOnline/urls.py

import xadmin

from django.urls import path,include,re_path

from django.views.generic import TemplateView
from users.views import LoginView,RegisterView,ActiveUserView,ForgetPwdView,ResetView,ModifyPwdView

from organization.views import OrgView
from django.views.static import serve
from MxOnline.settings import MEDIA_ROOT


urlpatterns = [
    path('xadmin/', xadmin.site.urls),
    path('', TemplateView.as_view(template_name='index.html'),name='index'),
    path('login/',LoginView.as_view(),name = 'login'),
    path('register/',RegisterView.as_view(),name = 'register'),
    path('captcha/',include('captcha.urls')),
    re_path('active/(?P<active_code>.*)/',ActiveUserView.as_view(),name='user_active'),
    path('forget/',ForgetPwdView.as_view(),name='forget_pwd'),
    re_path('reset/(?P<active_code>.*)/', ResetView.as_view(), name='reset_pwd'),
    path('modify_pwd/', ModifyPwdView.as_view(), name='modify_pwd'),

    path('org_list/',OrgView.as_view(),name = 'org_list'),
    # 处理图片显示的url,使用Django自带serve,传入参数告诉它去哪个路径找,我们有配置好的路径MEDIAROOT
    re_path(r'^media/(?P<path>.*)', serve, {"document_root": MEDIA_ROOT }),
]
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')
Django+xadmin打造在线教育平台(四)
# organization/views.py

from django.shortcuts import render

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

from django.http import HttpResponse
from .forms import UserAskForm

class OrgView(View):
    '''课程机构'''

    def get(self, request):
        # 所有课程机构
        all_orgs = CourseOrg.objects.all()

        # 所有城市
        all_citys = CityDict.objects.all()
        # 城市筛选
        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)

        # 热门课程机构排名
        hot_orgs = all_orgs.order_by('-click_nums')[:3]
        # 学习人数和课程数筛选
        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()
        # 对课程机构进行分页
        # 尝试获取前台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,
            "category": category,
            'hot_orgs':hot_orgs,
            'sort':sort,
        })


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>
Django+xadmin打造在线教育平台(四)
{#templates/org-list.html#}
{% extends 'base.html' %}
{% load staticfiles %}

{% block title %}课程机构列表{% endblock %}


{% block custom_bread %}
    <section>
        <div class="wp">
            <ul class="crumbs">
                <li><a href="index.html">首页</a>></li>
                <li>课程机构</li>
            </ul>
        </div>
    </section>
{% endblock %}


{% block content %}
    <section>
        <div class="wp butler_list_box list">
            <div class='left'>
                <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 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>
                        <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>
                    </ul>
                </div>

                <div class="all">共<span class="key">{{ org_nums }}</span>家</div>

                <div class="butler_list company list">
                    <div class="layout">
                        <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>


                        {% for course_org in all_orgs.object_list %}
                            <dl class="des difdes">

                                <dt>
                                    <a href="org-detail-homepage.html">

                                        <img width="200" height="120" class="scrollLoading"
                                             data-url="{{ MEDIA_URL }}{{ course_org.image }}"/>

                                    </a>
                                </dt>
                                <dd>
                                    <div class="clearfix">
                                        <a href="org-detail-homepage.html">
                                            <h1>{{ course_org.name }}</h1>
                                            <div class="pic fl">

                                                <img src="{% static 'images/authentication.png' %}"/>

                                                <img src="{% static 'images/gold.png' %}"/>

                                            </div>
                                        </a>
                                    </div>
                                    <ul class="cont">
                                        <li class="first"><p class="pic9">课程数:<span>1</span></p>
                                            <p class="c7">学习人数:<span>1000</span></p></li>
                                        <li class="c8" style="padding-left:18px;">北京市海淀区中关村北大街</li>
                                        <li class="pic10" style="padding-left:18px;">经典课程:

                                            <a href="/diary/19/">c语言基础入门</a>

                                            <a href="/diary/16/">数据库基础</a>

                                        </li>
                                    </ul>
                                </dd>
                                <div class="buy start_groupbuy jsShowPerfect2" data-id="22"><br/>联系<br/>服务</div>
                            </dl>
                        {% endfor %}


                    </div>
                    <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>

                </div>
            </div>

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



            <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>
        </div>
    </section>
{% endblock %}


<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全部代码

 

提交数据不合法时

Django+xadmin打造在线教育平台(四)

 

 合法时,提示成功信息,数据保存到数据库

 Django+xadmin打造在线教育平台(四)

 

7.7.机构首页

(1)给courses添加一个外键

from organization.models import CourseOrg

course_org = models.ForeignKey(CourseOrg, on_delete=models.CASCADE, verbose_name="所属机构", null=True, blank=True)
Django+xadmin打造在线教育平台(四)
# course/models.py

from datetime import datetime

from django.db import models
from organization.models import CourseOrg


class Course(models.Model):
    DEGREE_CHOICES = (
        ("cj", "初级"),
        ("zj", "中级"),
        ("gj", "高级")
    )
    name = models.CharField("课程名",max_length=50)
    desc = models.CharField("课程描述",max_length=300)
    detail = models.TextField("课程详情")
    degree = models.CharField('难度',choices=DEGREE_CHOICES, max_length=2)
    learn_times = models.IntegerField("学习时长(分钟数)",default=0)
    students = models.IntegerField("学习人数",default=0)
    fav_nums = models.IntegerField("收藏人数",default=0)
    image = models.ImageField("封面图",upload_to="courses/%Y/%m",max_length=100)
    click_nums = models.IntegerField("点击数",default=0)
    add_time = models.DateTimeField("添加时间",default=datetime.now,)
    course_org = models.ForeignKey(CourseOrg, on_delete=models.CASCADE, verbose_name="所属机构", null=True, blank=True)

    class Meta:
        verbose_name = "课程"
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name
全部代码

在后台添加课程和讲师

(2)模板

 把课程机构页面的四个文件拷贝到templates目录下

Django+xadmin打造在线教育平台(四)

新建一个模板,命名为“org_base.html”,复制org-detail-homepage.html的内容到里面

添加block,修改静态文件路径

Django+xadmin打造在线教育平台(四)

Django+xadmin打造在线教育平台(四)

Django+xadmin打造在线教育平台(四)

Django+xadmin打造在线教育平台(四)
{#templates/org_base.html#}

{% load staticfiles %}
<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <meta name="renderer" content="webkit">
    <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1" >
    <title>{% block title %}机构首页{% endblock %}</title>
    <link rel="stylesheet" type="text/css" href="{% static 'css/reset.css' %}">
    <link rel="stylesheet" type="text/css" href="{% static 'css/animate.css' %}">
    <link rel="stylesheet" type="text/css" href="{% static 'css/style.css' %}">
    <link rel="stylesheet" type="text/css" href="{% static 'js/plugins/queryCity/css/cityLayout.css' %}">
    {% block custom_css %}{% endblock %}
    <script src="{% static 'js/jquery.min.js' %}" type="text/javascript"></script>
    <script src="{% static 'js/jquery-migrate-1.2.1.min.js' %}" type="text/javascript"></script>
    {% block custom_js %}{% endblock %}
</head>
<body>
<section class="headerwrap headerwrap2">
    <header>
        <div  class="header2 header">

                <div class="top">
                <div class="wp">
                    <div class="fl">
                        <p>联系方式:<b>3333333333</b></p>
                    </div>
                    <a style="color:white" class="fr registerbtn" href="register.html">注册</a>
                    <a style="color:white" class="fr loginbtn" href="login.html">登录</a>
                </div>
            </div>


    <div class="middle companyheader">
        <div class="wp">
            <img class="fl" style="width: 112px;height: 103px" src="{% static 'media/org/2016/11/imooc.png' %}"/>
            <div class="head fl">
                <h1>
                    慕课网
                    <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>
    </header>
</section>
<section>
    <div class="wp">
        <ul  class="crumbs">
            <li><a href="index.html">首页</a>></li>
            <li><a href="org-list.html">课程机构</a>></li>
            <li>{% block page_path %}机构首页{% endblock %}</li>
        </ul>
    </div>
</section>

<section>
    <div class="wp list personal_list comp">
        <div class="left">
            <ul>
                <li class="active2"><a href="org-detail-homepage.html">机构首页</a></li>
                <li class=""><a href="org-detail-course.html">机构课程</a></li>
                <li class=""><a href="org-detail-desc.html">机构介绍</a></li>
                <li class=""><a href="org-detail-teachers.html">机构讲师</a></li>
            </ul>
        </div>

    {% block right_form %}
    {% endblock %}

    <div class="head">
        <h1>机构介绍</h1>
        <a class="green fr more" href="org-detail-desc.html">查看更多  >  </a>
    </div>
    <div class="cont">&nbsp; &nbsp; <p>&nbsp; &nbsp;</p><h1 class="ue_t" label="Title center" name="tc" style="border-bottom-color:#cccccc;border-bottom-width:2px;border-bottom-style:solid;padding:0px 4px 0px 0px;text-align:center;margin:0px 0px 20px;"><span style="color:#c0504d;">[键入文档标题]</span></h1><p style="text-align:center;"><strong class="ue_t">[键入文档副标题]</strong></p><h3><span class="ue_t" style="font-family:幼圆">[标题 1]</span></h3><p class="ue_t" style="text-indent:2em;">对于“插入”选项卡上的库,在设计时都充分考虑了其中的项与文档整体外观的协调性。 您可以使用这些库来插入表格、页眉、页脚、列表、封面以及其他文档构建基块。 您创建的图片、图表或关系图也将与当前的文档外观协调一致。</p><p class="ue_t" style="text-indent:2em;"><img src="../media/courses/ueditor/57aa86a0000145c512000460_20161210234050_865.jpg" title="" alt="57aa86a0000145c512000460.jpg"/> </p><h3><span class="ue_t" style="font-family:幼圆">[标题 2]</span></h3><p><img src="http://api.map.baidu.com/staticimage?center=116.410899,39.863624&zoom=11&width=530&height=340&markers=116.404,39.915" width="530" height="340"/> </p><p class="ue_t" style="text-indent:2em;">在“开始”选项卡上,通过从快速样式库中为所选文本选择一种外观,您可以方便地更改文档中所选文本的格式。 您还可以使用“开始”选项卡上的其他控件来直接设置文本格式。大多数控件都允许您选择是使用当前主题外观,还是使用某种直接指定的格式。</p><h3><span class="ue_t" style="font-family:幼圆">[标题 3]</span></h3><p>2016-12-10</p><p class="ue_t">对于“插入”选项卡上的库,在设计时都充分考虑了其中的项与文档整体外观的协调性。 您可以使用这些库来插入表格、页眉、页脚、列表、封面以及其他文档构建基块。 您创建的图片、图表或关系图也将与当前的文档外观协调一致。</p><p class="ue_t"><br/> </p><p><br/></p><p><br/></p><a href="/company/desc/22/"><span class="green">[查看更多]</span></a></div>
</div>


</section>
<!--sidebar start-->
<section>
    <ul class="sidebar">
        <li class="qq">
            <a target="_blank" href="http://wpa.qq.com/msgrd?v=3&uin=2023525077&site=qq&menu=yes"></a>
        </li>
        <li class="totop"></li>
    </ul>
</section>
<!--sidebar end-->
<!--header start-->
</div>
<!--弹出省省市-->
<script src="{% static 'js/selectUi.js' %}" type='text/javascript'></script>
<script type="text/javascript" src="{% static 'js/plugins/laydate/laydate.js' %}"></script>
<script src="{% static 'js/plugins/layer/layer.js' %}"></script>
<script src="{% static 'js/plugins/queryCity/js/public.js' %}" type="text/javascript"></script>

<script type="text/javascript" src="{% static 'js/plugins/jquery.raty.js' %}"></script>
<script type="text/javascript">
    //收藏分享
//收藏分享
function add_fav(current_elem, fav_id, fav_type){
    $.ajax({
        cache: false,
        type: "POST",
        url:"/org/add_fav/",
        data:{'fav_id':fav_id, 'fav_type':fav_type},
        async: true,
        beforeSend:function(xhr, settings){
            xhr.setRequestHeader("X-CSRFToken", "5I2SlleZJOMUX9QbwYLUIAOshdrdpRcy");
        },
        success: function(data) {
            if(data.status == 'fail'){
                if(data.msg == '用户未登录'){
                    window.location.href="login.html";
                }else{
                    alert(data.msg)
                }

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

$('.collectionbtn').on('click', function(){
    add_fav($(this), 1, 2);
});

$(function(){
    var $precision = $('.precision'),
        score = $precision.attr('data-star-scope'),
        option =  {
                    half        : true,
                    path        : '../images/',
                    precision    : true,
                    size        : 24,
                    starOff        : 'g_star.png',
                    starOn        : 'r_star.png',
                    starHalf    : 'h_star.png',
                    hints       : ['极差', '差', '一般', '好评', '非常满意'],
                    noRatedMsg  : '暂时还未获得评价!',
                    readOnly    : true,
                    score       : score
                };
    $precision.raty(option);

    $('.jsFavBtn').on('click', function(){
        var type = $(this).attr('data-fav-type');
        if(type == '1'){
            favPraise($(this), 'fav' ,1 , '收藏');

        }else if(type == '3'){
            favPraise($(this), 'fav' ,3 );

        }else if(type == '11'){
            favPraise($(this), 'pra', 1);

        }else if(type == '4'){
            favPraise($(this), 'fav' ,4 );

        }
    });
})
</script>


<script type="text/javascript">
$(function() {
    $('.recordbtn1').click(function(){
        $('.recordbox1').show();
    });
    $('.recordbtn2').click(function(){
        $('.recordbox2').show();
    });

    $('.imgslide').unslider({
        speed: 500,               //  The speed to animate each slide (in milliseconds)
        delay: 3000,              //  The delay between slide animations (in milliseconds)
        complete: function() {},  //  A function that gets called after every slide animation
        keys: true,               //  Enable keyboard (left, right) arrow shortcuts
        dots: true,               //  Display dot navigation
        fluid: false              //  Support responsive design. May break non-responsive designs
    });
    var unslider = $('.imgslide').unslider();
    $('.unslider-arrow').click(function() {
        var fn = this.className.split(' ')[1];
        unslider.data('unslider')[fn]();
    });
});
</script>

</body>
</html>
org_base.html

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

把org_base中的三个“right”剪切到home里面

Django+xadmin打造在线教育平台(四)

 

(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中修改链接,点击机构,跳到对应机构主页

Django+xadmin打造在线教育平台(四)

(6)修改org-base.html

 Django+xadmin打造在线教育平台(四)

Django+xadmin打造在线教育平台(四)

 

 (7)为teacher添加一个图形字段

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

(8)显示机构教师

Django+xadmin打造在线教育平台(四)

 

 (9)显示机构详情

Django+xadmin打造在线教育平台(四)

机构 首页:

 Django+xadmin打造在线教育平台(四)

 

Django+xadmin打造在线教育平台(四)

 

7.8.机构课程

 (1)模板文件

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

Django+xadmin打造在线教育平台(四)