1.点赞

2.弹窗登录


1.点赞

\blog\home\urls.py

path('like_change', views.like_change, name='like_change'),
\blog\home\views.py

def ErrorResponse(code, message):
    data = {}
    data['status'] = 'ERROR'
    data['code'] = code
    data['message'] = message

    return JsonResponse(data)


def SuccessResponse(liked_num):
    data = {}
    data['status'] = 'SUCCESS'
    data['liked_num'] = liked_num
    print(data)

    return JsonResponse(data)


def like_change(request):
    print("点赞")
    # 获取数据
    user = request.user

    content_type = request.GET.get('content_type')

    object_id = request.GET.get('object_id')

    try:
        content_type = ContentType.objects.get(model=content_type)
        model_class = content_type.model_class()
        model_obj = model_class.objects.get(pk=object_id)

    except ObjectDoesNotExist:
        return ErrorResponse(401, 'object not exist')

    # 处理数据
    if request.GET.get('is_like') == 'true':
        # 要点赞
        if not user.is_authenticated:
            return ErrorResponse(400, '没有登录,不能点赞')

        like_record, created = LikeRecord.objects.get_or_create(content_type=content_type, object_id=object_id,
                                                                user=user)
        # print(like_record, created)
        if created:
            # 未点赞过,进行点赞
            like_count, created = LikeCount.objects.get_or_create(content_type=content_type, object_id=object_id)
            like_count.liked_num += 1
            like_count.save()
            return SuccessResponse(like_count.liked_num)
        else:
            # 已点赞过,不能重复点赞
            return ErrorResponse(402, 'you were liked')
    else:
        # 要取消点赞
        if LikeRecord.objects.filter(content_type=content_type, object_id=object_id, user=user).exists():
            # 有点赞过,取消点赞
            like_record = LikeRecord.objects.get(content_type=content_type, object_id=object_id, user=user)
            like_record.delete()
            # 点赞总数减1
            like_count, created = LikeCount.objects.get_or_create(content_type=content_type, object_id=object_id)
            if not created:
                like_count.liked_num -= 1
                like_count.save()
                return SuccessResponse(like_count.liked_num)
            else:
                return ErrorResponse(404, 'data error')
        else:
            # 没有点赞过,不能取消
            return ErrorResponse(403, 'you were not liked')
\blog\home\models.py

class LikeCount(models.Model):
    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey('content_type', 'object_id')

    liked_num = models.IntegerField(default=0)

class LikeRecord(models.Model):
    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey('content_type', 'object_id')

    user = models.ForeignKey(User, on_delete=models.CASCADE)
    liked_time = models.DateTimeField(auto_now_add=True)
\blog\home\templatetags\comment_tags.py

register = template.Library()
@register.simple_tag
def get_like_count(obj):
    content_type = ContentType.objects.get_for_model(obj)
    like_count, created = LikeCount.objects.get_or_create(content_type=content_type, object_id=obj.id)
    return like_count.liked_num


@register.simple_tag(takes_context=True)
def get_like_status(context, obj):
    content_type = ContentType.objects.get_for_model(obj)
    user = context['user']
    if not user.is_authenticated:
        return ''
    if LikeRecord.objects.filter(content_type=content_type, object_id=obj.id, user=user).exists():
        return 'active'
    else:
        return ''


@register.simple_tag
def get_content_type(obj):
    content_type = obj._meta.model_name

    return content_type
\blog\templates\include\scroll_top.html
<!--detail显示赞手,可以点赞-->
<div class="like" onclick="likeChange(this, '{% get_content_type article %}', {{ article.id }})">
 <span class="fa fa-thumbs-o-up {% get_like_status article %}"></span>
 <span class="liked-num">{% get_like_count article %}</span>
 <span>喜欢</span>
</div>
\blog\templates\index.html
<!--赞手显示主页-->
<span ><i class="fa fa-thumbs-o-up" style="color:red"></i>{% get_like_count article %}&nbsp;</span>

\blog\templates\detail.html

                    {% for comment in comments %}
                        <div id="root_{{ comment.id }}" class="comment">
                            <p><strong style="color: pink"></strong></p>
                            <div><span><strong
                                    id="replay_user_{{ comment.id }}">{{ comment.user.mobile }}</strong></span>&nbsp;<span
                                    style="color: gray">{{ comment.created | date:'Y-m-d H:i:s' }}</span></div>
                            <br>

                            <div id="comment_{{ comment.id }}">
                                {{ comment.content|safe }}
                            </div>


                            <a href="javascript:reply({{ comment.id }});">回复</a>

                            {# 点赞 #}
                            <div class="like"
                                 onclick="likeChange(this, '{% get_content_type comment %}', {{ comment.id }})">
                                <span class="fa fa-thumbs-o-up {% get_like_status comment %}"></span>
                                <span class="liked-num">{% get_like_count comment %}</span>

                            </div>

                            {% for reply in comment.root_comment.all %}
                                <div class="reply">
                                    <span><strong
                                            id="replay_user_{{ reply.id }}">{{ reply.user.mobile }}</strong></span>
                                    &nbsp;<span>{{ reply.created | date:'Y-m-d H:i:s' }}</span>:
                                    &nbsp;<span>回复</span>&nbsp;
                                    <span><strong
                                            id="replay_user_{{ reply.id }}">{{ reply.reply_to.mobile }}</strong></span>

                                    <div id="comment_{{ reply.id }}">
                                        <span>{{ reply.content|safe }}</span>
                                    </div>

                                    <a href="javascript:reply({{ reply.id }});">回复</a>

                                    {# 点赞 #}
                                    <div class="like"
                                         onclick="likeChange(this, '{% get_content_type reply %}', {{ reply.id }})">
                                        <span class="fa fa-thumbs-o-up {% get_like_status reply %}"></span>
                                        <span class="liked-num">{% get_like_count reply %}</span>
                                    </div>

                                </div>

                            {% endfor %}
                        </div>
                    {% endfor %}

 

\blog\templates\include\selfcss.html

<style>   
   div.like {
    color: #337ab7;
    cursor: pointer;
    display: inline-block;
    padding: 0.5em 0.3em;
    }

    div.like .active{
        color: #f22;
    }
</style>
\blog\templates\detail.html

<script type="text/javascript">
 {#点赞#}
    function likeChange(obj, content_type, object_id){
            var is_like = obj.getElementsByClassName('active').length == 0
            $.ajax({
                url: "{% url 'home:like_change' %}",
                type: 'GET',
                data: {
                    content_type: content_type,
                    object_id: object_id,
                    is_like: is_like
                },
                cache: false,
                success: function(data){
                    console.log(data);

                    if(data['status']=='SUCCESS'){
                        // 更新点赞状态
                        var element = $(obj.getElementsByClassName('fa'));
                        if(is_like){
                            element.addClass('active');
                        }else{
                            element.removeClass('active');
                        }
                        // 更新点赞数量
                        var liked_num = $(obj.getElementsByClassName('liked-num'));
                        liked_num.text(data['liked_num']);
                    }else{
                        {#判断用户是否登录#}
                        if(data['code']==400){
                        $('#login_modal').modal('show');
                    }
                        else{
                        alert(data['message']);}
                    }
                },
                error: function(xhr){
                    console.log(xhr)
                }
            });
        }

</script>

2.弹窗登录

\blog\users\urls.py

# 弹窗登录
path('login_for_model', views.login_for_model, name='login_for_model'),
\blog\users\views.py

from users.forms import LoginForm
class DetailView(View):
    def get(self, request):
        context = {
            'login_form': LoginForm,
        }



def login_for_model(request):
    from django.contrib import auth
    login_form = LoginForm(request.POST)
    # print(login_form)
    data = {}
    if login_form.is_valid():
        user = login_form.cleaned_data['user']
        auth.login(request, user)
        data['status'] = 'SUCCESS'
    else:
        data['status'] = 'ERROR'
    return JsonResponse(data)

 在users文件夹下新建context_processors.py

\blog\users\context_processors.py

from .forms import LoginForm

def login_modal_form(request):
    return {'login_modal_form': LoginForm()}

在settings.py TEMPLATES 插入'users.context_processors.login_modal_form',

\blog\blog\settings.py

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, "templates")],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                
                # 自定义全局使用文件里面方法,如在loginmodal.html使用
                'users.context_processors.login_modal_form',
            ],
        },
    },
]

把弹窗登录html和js放到公共base.html里 ,并修改全局的login_modal_form,如{% for filed in login_modal_form %}

\blog\templates\include\base.html

<!-- 模态框登录-->
<div class="modal fade" id="login_modal">
    <div class="modal-dialog ">
        <div class="modal-content ">

            <form action="" method="POST" id="login_model_form" style="padding: 20px 20px;">
                <!-- 模态框头部 -->
                <div class="modal-header">
                    <h4 class="modal-title">登录账号</h4>
                    <button type="button" class="close" data-dismiss="modal">&times;</button>
                </div>
                {#<!-- 模态框主体 -->#}
                {% csrf_token %}
                {# login_modal_form在全局settings里, #}
                {% for filed in login_modal_form %}

                    {# 去冒号, #}
                    <label for="{{ filed.id_for_label }}">{{ filed.label }}</label>
                    {{ filed }}
                {% endfor %}
                <spen id='login_model_tips' class="text-danger"></spen>

                <small class="form-text text-muted ml-1">还没有账号?<a href="{% url 'users:register' %}"
                                                                  style="color: cornflowerblue; ">注册新账号</a></small>
                <br>
                <div class="custom-control custom-checkbox mb-2">
                    <input type="checkbox" name="remember" id="id_remember" checked class="custom-control-input">
                    <label for="id_remember" class="custom-control-label">保持登录</label>
                </div>
                <button class="primaryAction btn btn-primary" type="submit" id="submit_login" @click="on_submit">登录
                </button>

                <!-- 模态框底部 -->
                <div class="modal-footer">
                    <button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>
                </div>
            </form>
        </div>
    </div>
</div>

<script type="text/javascript">
    //弹窗登录
    $("#login_model_form").submit(function (event) {
        event.preventDefault();
        $.ajax({
            url: "{% url 'users:login_for_model' %}",
            type: 'POST',
            data: $(this).serialize(),
            cache: false,
            success: function (data) {
                if (data['status'] == 'SUCCESS') {
                    window.location.reload();
                } else {
                    $('#login_model_tips').text('用户名或密码不正确');
                }
            }
        });
    });
</script>

效果图