美文网首页
Django+Xadmin打造在线教育系统(四)

Django+Xadmin打造在线教育系统(四)

作者: 听你讲故事啊 | 来源:发表于2018-09-17 20:36 被阅读0次

    完成授课机构的功能

    模板继承

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

    TIM截图20180908154416.png TIM截图20180908153932.png

    编写org-list.html内容
    继承base.html,将里面的面包屑和内容拷贝到org-list.html

    TIM截图20180908170242.png

    配置路由

        # 课程机构首页url
        path('org_list/', OrgView.as_view(), name="org_list"),
    

    这里需要修改一下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="机构类别", default="pxjg")
    

    修改了models之后做数据库的变动:

    makemigrations organization
    migrate organization
    

    在项目目录下面新建一个目录media,用来存放上传的图片
    setting中要配置我们把文件存放在哪个根目录之下

    # 设置我们上传文件的路径
    
    MEDIA_URL = '/media/'
    MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
    

    在后台自行添加教育机构和城市

    添加完数据后进行逻辑代码的编写

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

    数据填充

    打开org-list.html进行数据的填充

    TIM截图20180908172234.png TIM截图20180908172309.png

    这里只保留一个dl标签即可,其他的数据自行填充
    这里说一下MEDIA_URL
    数据库中存储的图片路径时没有/media/前缀的

    TIM截图20180908172547.png

    如果想要使用MEDIA_RUL需要在设置中添加media处理器

    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',
                ],
            },
        },
    ]
    

    然后还需要配url

    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内置的由分页模块,而是使用插件django-pure-pagination

    pip install django-pure-pagination
    

    进行settings的配置

    INSTALLED_APPS = (
        ...
        'pure_pagination',
    )
    
    PAGINATION_SETTINGS = {
        'PAGE_RANGE_DISPLAYED': 10,
        'MARGIN_PAGES_DISPLAYED': 2,
        'SHOW_FIRST_PAGE_WHEN_INVALID': True,
    }
    

    这里参考官方的例子进行配置

    from pure_pagination import Paginator, EmptyPage, PageNotAnInteger
    class OrgView(View):
        def get(self,request):
            # 查找到所有的课程机构
            all_orgs = CourseOrg.objects.all()
            # 总共有多少家机构使用count进行统计
            org_nums = all_orgs.count()
            # 取出所有的城市
            all_city = 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_city": all_city,
                "org_nums": org_nums,
            })
    

    在html文件中进行分页
    这里for循环需要使用object_list

     {% for org in 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>
    

    分类筛选功能

    点击某个城市时,该城市处于选中状态,下面显示的数据是当前城市的

    class OrgView(View):
        def get(self,request):
            # 查找到所有的课程机构
            all_orgs = CourseOrg.objects.all()
    
            # 取出所有的城市
            all_city = CityDict.objects.all()
    
            city_id = request.GET.get('city', '')
            if city_id:
                all_orgs = all_orgs.filter(city_id=int(city_id))
    
            # 总共有多少家机构使用count进行统计
            org_nums = all_orgs.count()
    
            # 对课程机构进行分页
            # 尝试获取前台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_city": all_city,
                "org_nums": org_nums,
                'city_id': city_id,
            })
    

    后台逻辑中给前端传递了一个city_id用来城市的标记

        <div class="cont">
            <a href="?ct="><span class="{% ifequal city_id '' %}active2{% endifequal %}">全部</span></a>
                {% for city in all_city %}
                    <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”

    同理,添加类别筛选

    # 类别筛选
    category = request.GET.get('ct','')
    if category:
        all_orgs = all_orgs.filter(category=category)
    
        <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_city %}
                <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。
    • 当两者都选的时候使用&连接。

    课程机构排名

        # 热门机构,如果不加负号会是有小到大。
         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取当前循环到第几次

    学习人数和课程的筛选

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

       # 当学生点击学习课程,找到所属机构,学习人数加1
       students = models.IntegerField(default=0, verbose_name=u"学习人数")
       # 当发布课程就加1
       course_nums =  models.IntegerField(default=0, verbose_name=u"课程数")
    
    makemigrations
    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")
    
        <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>
    

    modelform 提交我要学习咨询

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

    # 普通版本的form
    # class UserAskForm(forms.Form):
    #     name = forms.CharField(required=True, min_length=2, max_length=20)
    #     phone = forms.CharField(required=True, max_length=11, min_length=11)
    #     course_name = forms.CharField(required=True, min_length=5, max_length=50)
    
    # 进阶版本的modelform:它可以向model一样save
    from django import forms
    
    from operation.models import UserAsk
    
    
    class AnotherUserForm(forms.ModelForm):
        # 继承之余还可以新增字段
    
        # 是由哪个model转换的
        class Meta:
            model = UserAsk
            # 我需要验证的字段
            fields = ['name','mobile','course_name']
    

    使用include进行路由分发
    organization目录下新建urls.py

    from django.urls import path
    
    from organization.views import OrgView, AddUserAskView
    
    app_name = "organization"
    
    urlpatterns = [
        # 课程机构首页url
        path('list/', OrgView.as_view(), name="org_list"),
    ]
    

    根目录下的urls.py
    删掉org_list,新增include

    # 课程机构app的url配置
    path("org/", include('organization.urls',namespace="org")),
    

    修改base.html中“课程机构的链接”

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

    后台逻辑代码

    # 用户添加我要学习
    class AddUserAskView(View):
        # 处理表单提交当然post
        def post(self,request):
            userask_form = UserAskForm(request.POST)
            # 判断该form是否有效
            if userask_form.is_valid():
                # 这里是modelform和form的区别
                # 它有model的属性
                # 当commit为true进行真正保存
                user_ask = userask_form.save(commit=True)
                # 这样就不需要把一个一个字段取出来然后存到model的对象中之后save
    
                # 如果保存成功,返回json字符串,后面content type是告诉浏览器的,
                return HttpResponse('{"status": "success"}', content_type='application/json')
            else:
                # 如果保存失败,返回json字符串,并将form的报错信息通过msg传递到前端
                return HttpResponse('{"status": "fail", "msg":{0}}'.format(userask_form.errors),  content_type='application/json')
    
    

    路由

        path('add_ask/', AddUserAskView.as_view(), name="add_ask"),
    

    前端页面采用Ajax方式请求
    form表单添加crsf_token

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

    在ModelForm中自定义一个手机号验证的方法

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

    机构详情

    • 机构首页
    • 机构课程
    • 机构介绍
    • 机构讲师

    课程中应该有一个外键指向它是哪个机构的

    # courses/models.py
    
    course_org = models.ForeignKey(CourseOrg,on_delete=models.CASCADE, verbose_name="所属机构",null=True,blank=True)
    
    makemigration 
    migrate 
    

    登录xadmin添加基础的必要数据。添加课程与讲师。
    新建一个模板,命名为“org_base.html”,复制org-detail-homepage.html的内容到里面,
    添加block,修改静态文件路径


    QQ截图20180909131632.png QQ截图20180909131658.png QQ截图20180909131719.png

    把org_base中的三个“right”剪切到home里面
    路由配置

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

    视图函数

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

    显示课程

        <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-base.html

    QQ截图20180909132619.png QQ截图20180909132708.png

    为讲师增加头像字段

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

    显示机构教师

        <div class="head">
                <h1>机构教师</h1>
                <a class="green fr more" href="org-detail-teachers.html">查看更多</a>
        </div>
    
        {% for teacher in all_teacher %}
            <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>java开发教程</h1></a>
                                <span>发表于:2015-10-12</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>
            <div class="cont">{{ course_org.desc }}</div>
        </div>
    

    机构课程

    配置路由

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

    视图函数

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

    修改org-base.html中left的链接

        <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="{% 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>
        </div>
    

    显示机构课程,修改org-detail-course.html

        {% block right_form %}
        <div class="right companycenter layout" >
                <div class="head">
                    <h1>机构课程</h1>
                </div>
                <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 %}
                    <div class="pageturn">
                        <ul class="pagelist">
                            <li class="active"><a href="?page=1">1</a></li>
                        </ul>
                    </div>
            </div>
        {% endblock %}
    

    左侧active修改

    因为现在没有值能判断当前是哪个页面。所以在orghomeview中传值回来current page
    修改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,
            })
    
    

    机构介绍

    re_path('desc/(?P<org_id>\d+)/', OrgDescView.as_view(), name="org_desc"),
    
    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,
            })
    
        {% block right_form %}
        <div class="right companycenter layout" >
                <div class="head">
                    <h1>机构介绍</h1>
                </div>
                <div class="des">
    
                    {{ course_org.desc }}
    
                </div>
            </div>
        {% endblock %}        
    

    机构讲师

    re_path('teacher/(?P<org_id>\d+)/', OrgTeacherView.as_view(), name="org_teacher"),
    
    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,
            })
    
        {% 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 %}
    

    重载我们的pagepath和title,使数据动态显示

        {% block title %}机构教师{% endblock %}
    
        {% block page_path %}
        机构教师
        {% endblock %}
    

    课程机构收藏功能

    path('add_fav/', AddFavView.as_view(), name="add_fav"),
    
    class AddFavView(View):
        """
        用户收藏与取消收藏功能
        """
        def post(self, request):
            # 表明你收藏的不管是课程,讲师,还是机构。他们的id
            # 默认值取0是因为空串转int报错
            id = request.POST.get('fav_id', 0)
            # 取到你收藏的类别,从前台提交的ajax请求中取
            type = request.POST.get('fav_type', 0)
    
            # 收藏与已收藏取消收藏
            # 判断用户是否登录:即使没登录会有一个匿名的user
            if not request.user.is_authenticated:
                # 未登录时返回json提示未登录,跳转到登录页面是在ajax中做的
                return HttpResponse('{"status":"fail", "msg":"用户未登录"}', content_type='application/json')
            exist_records = UserFavorite.objects.filter(user=request.user, fav_id=int(id), fav_type=int(type))
            if exist_records:
                # 如果记录已经存在, 则表示用户取消收藏
                exist_records.delete()
                return HttpResponse('{"status":"success", "msg":"收藏"}', content_type='application/json')
            else:
                user_fav = UserFavorite()
                # 过滤掉未取到fav_id type的默认情况
                if int(type) >0 and int(id) >0:
                    user_fav.fav_id = int(id)
                    user_fav.fav_type = int(type)
                    user_fav.user = request.user
                    user_fav.save()
                    return HttpResponse('{"status":"success", "msg":"已收藏"}', content_type='application/json')
                else:
                    return HttpResponse('{"status":"fail", "msg":"收藏出错"}', content_type='application/json')
    

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

    还有个问题就是,刷新页面后,“已收藏”就变成“收藏”,是因为在返回页面的时候,没有判断收藏状态, 所有要在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
    
    # return redener加上值
        "has_fav": has_fav
    

    四个view都要添加

    class OrgDescView(View):
        '''机构介绍页'''
        def get(self, request, org_id):
            current_page = 'desc'
            # 根据id取到课程机构
            course_org = CourseOrg.objects.get(id= int(org_id))
    
            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
            return render(request, 'org-detail-desc.html',{
                'course_org': course_org,
                'current_page':current_page,
                'has_fav': has_fav,
            })
    

    前台 org_base.html

        <div class="btn fr collectionbtn  notlogin 
             "data-favid="22" data-fav-type="1">
             {% if has_fav %}已收藏{% else %}收藏{% endif %}
        </div>
    

    相关文章

      网友评论

          本文标题:Django+Xadmin打造在线教育系统(四)

          本文链接:https://www.haomeiwen.com/subject/crudnftx.html