点赞,弹窗登录的全局路径完善
\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 %} </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> <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>
<span>{{ reply.created | date:'Y-m-d H:i:s' }}</span>:
<span>回复</span>
<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>
\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">×</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>
效果图
评论列表 (0 条评论)