K12协同开发在做常见问题时候遇到的问题
一、在做常见问题的时候遇到的问题
在后端处理数据的时候是通过serialize来实现的,从数据库中查出自己想要的数据,直接返回数据。
在前端发送ajax请求获取数据并且在页面上以好看的形式渲染。
1、相关的表
class Course(models.Model): """课程""" name = models.CharField(max_length=128, unique=True) course_img = models.CharField(max_length=255) sub_category = models.ForeignKey("CourseSubCategory") course_type_choices = ((0, '付费'), (1, 'VIP专享'), (2, '学位课程')) course_type = models.SmallIntegerField(choices=course_type_choices) degree_course = models.ForeignKey("DegreeCourse", blank=True, null=True, help_text="若是学位课程,此处关联学位表") brief = models.TextField(verbose_name="课程概述", max_length=2048) level_choices = ((0, '初级'), (1, '中级'), (2, '高级')) level = models.SmallIntegerField(choices=level_choices, default=1) pub_date = models.DateField(verbose_name="发布日期", blank=True, null=True) period = models.PositiveIntegerField(verbose_name="建议学习周期(days)", default=7) order = models.IntegerField("课程顺序", help_text="从上一个课程数字往后排") attachment_path = models.CharField(max_length=128, verbose_name="课件路径", blank=True, null=True) status_choices = ((0, '上线'), (1, '下线'), (2, '预上线')) status = models.SmallIntegerField(choices=status_choices, default=0) template_id = models.SmallIntegerField("前端模板id", default=1) coupon = GenericRelation("Coupon") # 用于GenericForeignKey反向查询,不会生成表字段,切勿删除 price_policy = GenericRelation("PricePolicy") def __str__(self): return "%s(%s)" % (self.name, self.get_course_type_display()) def save(self, *args, **kwargs): if self.course_type == 2: if not self.degree_course: raise ValueError("学位课程必须关联对应的学位表") super(Course, self).save(*args, **kwargs) class OftenAskedQuestion(models.Model): """常见问题""" content_type = models.ForeignKey(ContentType, limit_choices_to={'model__contains': 'course'}) # 关联course or degree_course object_id = models.PositiveIntegerField() content_object = GenericForeignKey('content_type', 'object_id') question = models.CharField(max_length=255) answer = models.TextField(max_length=1024) def __str__(self): return "%s-%s" % (self.content_object, self.question) class Meta: unique_together = ('content_type', 'object_id', 'question')
serializer
class CourseQuestionSerializer(ModelSerializer): class Meta: model = models.OftenAskedQuestion fields = ['question','answer'] depth = 2
由上面的表发现是课程和问题是通过content_type 关联的。所以我们在通过课程去查询问题的时候。要利用contenttype去查找
2、后端开发
from django.contrib.contenttypes.models import ContentType print(course_obj._meta.model_name,'表名') #查看当前的表名
course_obj = model.Course.objects.filter(pk=kwargs.get('pk')).first() #首先找到课程的id
ct_id = ContentType.objects.filter(app_label='api', model=course_obj._meta.model_name).first().id #找到表类型的id
o_list = models.OftenAskedQuestion.objects.filter(content_type_id=ct_id, object_id=course_obj.id) #然后通过课程的id去找课程相关联的问题
ser = my_seri.CourseQuestionSerializer(instance=o_list, many=True) #吧查到的所有问题进行序列化
print(ser.data)
res["data"] = ser.data
return JsonResponse(res) #返回数据
3、前端开发
通过vue框架发送ajax请求
<ul class="tab"> <li @click="coursebrief()">课程概述</li> <li @click="coursechapters()">课程章节</li> <li @click="coursequestion">常见问题</li> </ul>
coursequestion(){ var that = this; this.$axios.request({ url:'http://127.0.0.1:8000/api/course/'+ this.pk+'.json'+'?data_type=question', method:'GET', responseType:'json' }).then(function (response) { console.log(response.data); that.question_list = response.data.data; #保存后端发过来的数据 console.log(that.question_list) }) } }
一开始设置默认
data () { return { question_list:[], } },
<div> <h1>常见问题</h1> <ul v-for="item in question_list"> <li>问:{{ item.question }}</li> <li>答:{{ item.answer }}</li> </ul> </div>
二、vue在前端实现tab切换
代码实现
<ul class="tab">
<!--<li v-for="(item, index) in tabs" :class="{active:index == num}" @click="tab(index)">{{item}}</li>-->
<li @click="tab('detail')">课程概述</li>
<li @click="tab('chapters')">课程章节</li>
<li @click="tab('question')">常见问题</li>
</ul>
1 <div class="detail box"> 2 <h3>可以根据不同的学习情况购买不一样的学习套餐哦!</h3> 3 <ul> 4 <li v-for="item in box.detail.priceList">{{item.price}}/{{item.valid_period}}</li> 5 </ul> 6 <div> 7 <h3>课程概述</h3> 8 <p>{{box.detail.brief}}</p> 9 </div> 10 <div> 11 <h3>为什么学习这门课程</h3> 12 <p>{{box.detail.why_study}}</p> 13 </div> 14 <div> 15 <h3>我将学到的内容</h3> 16 <ol> 17 <li v-for="item in box.detail.outlineList">{{item.title}} 18 <div>{{item.content}}</div> 19 </li> 20 </ol> 21 </div> 22 <div> 23 <h3>此项目如何有助于我的职业生涯?</h3> 24 <p>{{box.detail.career_improvement}}</p> 25 </div> 26 <div> 27 <h3>课程先修要求</h3> 28 <p>{{box.detail.prerequisite}}</p> 29 </div> 30 <div> 31 <h3>课程讲师简介</h3> 32 <ul> 33 <li v-for="item in box.detail.teacherList"> 34 {{item.name}} {{item.title}} {{item.brief}} 35 </li> 36 </ul> 37 </div> 38 </div> 39 <div class="chapters box"> 40 <ul> 41 <li v-for="item in box.chapters"> 42 第{{item.chapter}}章 | {{item.name}} 43 <ul> 44 <li v-for="section in item.coursesections"> 45 {{section.name}} 46 </li> 47 </ul> 48 </li> 49 </ul> 50 </div> 51 <div class="comment box"> 52 53 </div> 54 <div class="question box"> 55 <h1>常见问题</h1> 56 <ul v-for="item in box.question_list"> 57 <li>问:{{ item.question }}</li> 58 <li>答:{{ item.answer }}</li> 59 </ul> 60 </div>
methods:{ tab(cls) { //实现tab切换 $(".box").each(function (index, ele) { console.log(index,ele,'........'); $(ele).css("display", "none") //循环一开始都设置成none,不显示 }); $("."+cls).css("display", "block") //然后把当前点击的那个设置成显示 },