核心是第3步和第5步:第3步收藏视图中的处理逻辑,第5步ajax如何发送请求并传递参数
1. 收藏的模型类:
class UserFavorite(BaseModel):
user = models.ForeignKey(UserProfile, on_delete=models.CASCADE, verbose_name="用户")
fav_id = models.IntegerField(verbose_name="数据ID")
fav_type = models.IntegerField(verbose_name="收藏类型", default=1,
choices=((1, "课程"), (2, "课程机构"), (3, "讲师")))
class Meta:
verbose_name = "用户收藏"
verbose_name_plural = verbose_name
def __str__(self):
return "{}_{}".format(self.user.username, self.fav_id)
2. 收藏的表单类
from django import forms
from apps.operations.models import UserFavorite
class UserFavForm(forms.ModelForm):
class Meta:
model = UserFavorite
fields = ["fav_id", "fav_type"]
def clean(self):
# 此处可以增加校验:收藏id是否存在,收藏种类是否存在
return self.cleaned_data
3. 收藏视图中的写法
from django.views.generic.base import View
from django.http import JsonResponse
from apps.operations.models import UserFavorite
from apps.operations.forms import UserFavForm
from apps.courses.models import Course
from apps.organizations.models import CourseOrg, Teacher
class AddFavView(View):
"""用户收藏,取消收藏"""
def post(self, request):
# 先判断用户是否登录
if not request.user.is_authenticated:
return JsonResponse({"status": "fail", "msg": "用户未登录"})
# 此处传递request.user对象,可以在UserFavForm类中进行校验使用
user_fav_form = UserFavForm(data=request.POST)
if user_fav_form.is_valid():
# 如果验证有效,获取数据id,和收藏的种类
# 此处也可以增加验证收藏id是否存在,收藏种类是否存在,也可以把此校验放到form中进行
fav_id = user_fav_form.cleaned_data["fav_id"]
fav_type = user_fav_form.cleaned_data["fav_type"]
# 2. 判断用户是否收藏过
existed_record = UserFavorite.objects.filter(user=request.user,
fav_id=fav_id,
fav_type=fav_type)
if existed_record:
# 如果用户已经收藏过了,在点击我们就认为是取消收藏,删除该用户的收藏记录
existed_record.delete()
# 同时我们应该把收藏总数量减1
if fav_type == 1:
course = Course.objects.get(id=fav_id)
course.fav_nums -= 1
course.save()
elif fav_type == 2:
org = CourseOrg.objects.get(id=fav_id)
org.fav_nums -= 1
org.save()
elif fav_type == 3:
teacher = Teacher.objects.get(id=fav_id)
teacher.fav_nums -= 1
teacher.save()
# 响应
return JsonResponse({"status": "success", "msg": "已取消收藏"})
else:
# 将收藏记录保存进数据库
UserFavorite.objects.create(user=request.user, fav_id=fav_id, fav_type=fav_type)
# 同时我们需要把收藏总数量加1
if fav_type == 1:
course = Course.objects.get(id=fav_id)
course.fav_nums += 1
course.save()
elif fav_type == 2:
org = CourseOrg.objects.get(id=fav_id)
org.fav_nums += 1
org.save()
elif fav_type == 3:
teacher = Teacher.objects.get(id=fav_id)
teacher.fav_nums += 1
teacher.save()
# 响应
return JsonResponse({"status": "success", "msg": "已收藏"})
else:
# 返回错误消息
return JsonResponse({"status": "fail", "msg": "参数错误"})
4. 详情视图中显示收藏与为收藏的代码中,需要增加一个收藏状态,前提还要判断用户是否已登录
class CourseDetailView(View):
def get(self, request, course_id):
"""课程详情页展示"""
course = Course.objects.get(id=int(course_id))
course.click_nums += 1
course.save()
# 查询课程所对应的机构
org = course.course_org
# 获取机构的收藏状态
is_org_collection = False
if request.user.is_authenticated:
if UserFavorite.objects.filter(user=request.user, fav_id=org.id, fav_type=2):
# 如果查到了,表示已收藏
is_org_collection = True
# 获取课程的收藏状态
is_course_collection = False
if request.user.is_authenticated:
if UserFavorite.objects.filter(user=request.user, fav_id=course.id, fav_type=1):
# 如果查到了,表示已收藏
is_course_collection = True
return render(request, "course-detail.html",
{"course": course, "org": org,
"is_org_collection": is_org_collection,
"is_course_collection": is_course_collection})
页面中在根据收藏状态判断显示已收藏还是收藏
5. ajax发送请求收藏与取消收藏
<script type="text/javascript">
//收藏分享
function add_fav(current_elem, fav_id, fav_type) {
$.ajax({
cache: false,
type: "POST",
url: "{% url 'ope: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 = "{% url 'users:login' %}";
} else {
alert(data.msg)
}
} else if (data.status == 'success') {
current_elem.text(data.msg)
}
},
});
}
$(document).ready(function () {
$('#jsLeftBtn').on('click', function () {
add_fav($(this), {
{ course.id }}, 1);
});
});
$(document).ready(function () {
$('#jsRightBtn').on('click', function () {
add_fav($(this), {
{ org.id }}, 2);
});
});
</script>