django项目中如何完成收藏与取消收藏的功能

核心是第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>

猜你喜欢

转载自blog.csdn.net/weixin_42289273/article/details/114750059
今日推荐