共计 10916 个字符,预计需要花费 28 分钟才能阅读完成。
指标成果:
html 的表单变成 django_form
在 comment 中创立 forms.py 文件,编写代码:
from django import forms
from django.contrib.contenttypes.models import ContentType
from django.db.models import ObjectDoesNotExist
from ckeditor.widgets import CKEditorWidget
class CommentForm(forms.Form):
content_type = forms.CharField(widget=forms.HiddenInput)
object_id = forms.IntegerField(widget=forms.HiddenInput)
text = forms.CharField(widget=CKEditorWidget(config_name='comment_ckeditor'),
error_messages={'required': '评论内容不能为空'})
def __init__(self, *args, **kwargs):
if 'user' in kwargs:
self.user = kwargs.pop('user')
super(CommentForm, self).__init__(*args, **kwargs)
def clean(self):
# 判断用户是否登录
if self.user.is_authenticated:
self.cleaned_data['user'] = self.user
else:
raise forms.ValidationError('用户尚未登录')
# 评论对象验证
content_type = self.cleaned_data['content_type']
object_id = self.cleaned_data['object_id']
try:
model_class = ContentType.objects.get(model=content_type).model_class()
model_obj = model_class.objects.get(pk=object_id)
self.cleaned_data['content_object'] = model_obj
except ObjectDoesNotExist: # 不应用 exceptions 的起因时为了避免将任何谬误都归因于评论对象不存在从而导致难以保护
raise forms.ValidationError('评论对象不存在')
return self.cleaned_data
在 comment 中的 views.py 中导入 Comment 并且在上面将该参数传递给前端,
from django.shortcuts import render, redirect
from django.contrib.contenttypes.models import ContentType
from django.urls import reverse
from django.http import JsonResponse
from .models import Comment
from .forms import CommentForm
def update_comment(request):
referer = request.META.get('HTTP_REFERER', reverse('home'))
comment_form = CommentForm(request.POST, user=request.user) # 实例化
data = {}
if comment_form.is_valid():
# 查看通过,保留数据
comment = Comment()
comment.user = comment_form.cleaned_data['user']
comment.text = comment_form.cleaned_data['text']
comment.content_object = comment_form.cleaned_data['content_object']
comment.save()
# 返回数据
data['status'] = 'SUCCESS'
data['username'] = comment.user.username
data['comment_time'] = comment.comment_time.strftime('%Y-%m-%d %H:%M:%S')
data['text'] = comment.text
else:
#return render(request, 'error.html', {'message': comment_form.errors, 'redirect_to': referer})
data['status'] = 'ERROR'
data['message'] = list(comment_form.errors.values())[0][0]
return JsonResponse(data)
而后再 blog_detail 中提价评论上面减少 {{comment_form}} 以退出渲染
<h3 class="comment-area-title"> 提交评论 </h3>
{% if user.is_authenticated %}
<form action="{% url'update_comment'%}" method="POST" style="overflow:hidden">
{% csrf_token %}
{{comment_form}}
<div class="form-group">
<label for="comment_text">{{user.username}},欢送评论~</label>
批改 blog/views.py 中 blog_detail
from comment.forms import CommentForm
......
def blog_detail(request, blog_pk):
context['comment_form'] = CommentForm(initial={'content_type': blog_content_type.model, 'object_id': blog_pk})
成果如下:
两个框,而且文本编辑性能欠缺,咱们优化并减少一下新性能:
将 blog\_detail.html 中的欢送评论四周简化款式, 并且优化:
新的
{# 删除和 base 中反复的内容,留下独有的内容, 而后别离填充到上面的两个 block 中 #}
{# 这是页面题目 #}
{% extends 'base.html' %}
{% block title %}{{blog.title}}{% endblock %}{# 这里因为之前 title 被包起来了,所以间接用变量即可 #}
{% block nav_blog_active %}active{% endblock %}
{% load static %}
{% block header_extends %}
<link rel="stylesheet" href="{% static'blog/blog.css'%}">
<script type="text/javascript" src="{% static"ckeditor/ckeditor-init.js"%}"></script>
<script type="text/javascript" src="{% static"ckeditor/ckeditor/ckeditor.js"%}"></script>
{% endblock %}
{# 页面内容 #}
{% block content %}
<div class="container">
<div class="row">
<div class="col-xs-10 col-xs-offset-1">
<h3>{{blog.title}}</h3>
<ul class="blog-info-description">
<li> 作者:{{blog.author}}</li>
<li> 分类:<a href="{% url'blogs_with_type'blog.blog_type.pk %}">{{blog.blog_type}}</a></li>
<li> 发表日期:{{blog.created_time|date:"Y-m-d H:i:s"}}</li>
<li> 浏览量:({{blog.get_read_num}})</li>
</ul>
<div class="blog-content">{{blog.content|safe}}</div>
<div class="blog-more">
<p> 上一篇:{% if previous_blog %}
<a href="{% url'blog_detail'previous_blog.pk %}">{{previous_blog.title}}</a>
{% else %}
没有了
{% endif %}
</p>
<p> 下一篇:{% if next_blog %}
<a href="{% url'blog_detail'next_blog.pk %}">{{next_blog.title}}</a>
{% else %}
没有了
{% endif %}
</p>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-10 col-xs-offset-1">
<div class="comment-area">
<h3 class="comment-area-title"> 提交评论 </h3>
{% if user.is_authenticated %}
<form id="comment_form" action="{% url'update_comment'%}" method="POST" style="overflow:hidden">
<label>{{user.username}},欢送评论~</label>
{% csrf_token %}
{% for field in comment_form %}
{{field}}
{% endfor %}
<span id="comment_error" class="text-danger pull-left"></span>
<input type="submit" value="评论" class="btn btn-primary pull-right">
</form>
{% else %}
您尚未登录,登录之后方可评论~
<a class="btn btn-primary" href="{% url'login'%}?from={{request.get_full_path}}"> 登录 </a>
<span> or </span>
<a class="btn btn-danger" href="{% url'register'%}?from={{request.get_full_path}}"> 注册 </a>
{% endif %}
</div>
<div class="comment-area">
<h3 class="comment-area-title"> 评论列表 </h3>
<div id="comment_list">
{% for comment in comments %}
<div>
{{comment.user.username}}
({{comment.comment_time|date:"Y-m-d H:i:s"}}):{{comment.text|safe}}
</div>
{% empty %}
暂无评论
{% endfor %}
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block script_extends %}
<script type="text/javascript">
$("#comment_form").submit(function(){
// 判断是否为空
$("#comment_error").text('');
if(CKEDITOR.instances["id_text"].document.getBody().getText().trim()==''){$("#comment_error").text('评论内容不能为空');
return false;
}
// 更新数据到 textarea
CKEDITOR.instances['id_text'].updateElement();
// 异步提交
$.ajax({url: "{% url'update_comment'%}",
type: 'POST',
data: $(this).serialize(),
cache: false,
success: function(data){console.log(data);
if(data['status']=="SUCCESS"){
// 插入数据
var comment_html = '<div>' + data['username'] +
'(' + data['comment_time'] + '):' +
data['text'] + '</div>';
$("#comment_list").prepend(comment_html);
// 清空编辑框的内容
CKEDITOR.instances['id_text'].setData('');
}else{
// 显示错误信息
$("#comment_error").text(data['message']);
}
},
error: function(xhr){console.log(xhr);
}
});
return false;
});
</script>
{% endblock %}
原来的:
<div class="row">
<div class="col-xs-10 col-xs-offset-1">
<div class="comment-area">
<h3 class="comment-area-title"> 提交评论 </h3>
{% if user.is_authenticated %}
<form action="{% url'update_comment'%}" method="POST" style="overflow:hidden">
{% csrf_token %}
{{comment_form}}
<div class="form-group">
<label for="comment_text">{{user.username}},欢送评论~</label>
<textarea id="comment_text" class="form-control" name="text" rows="4"></textarea>
{# 应用 input 无奈多行输出,换成 textarea 来写多行内容, 应用 bootstrap 中的 form-control 对编辑区域和提交性能的性能优化 #}
</div>
<input type="hidden" name="object_id" value="{{blog.pk}}">
<input type="hidden" name="content_type" value="blog">
<input type="submit" value="评论" class="btn btn-primary" style="float:right">
</form>
{% else %}
您尚未登录,登录之后方可评论~
<a class="btn btn-primary" href="{% url'login'%}?from={{request.get_full_path}}"> 登录 </a>
<span> or </span>
<a class="btn btn-danger" href="{% url'register'%}?from={{request.get_full_path}}"> 注册 </a>
{% endif %}
</div>
<div class="comment-area">
<h3 class="comment-area-title"> 评论列表 </h3>
{% for comment in comments %}
<div>
{{comment.user.username}}
({{comment.comment_time|date:"Y-m-d H:n:s"}}):{{comment.text}}
</div>
{% empty %}
暂无评论
{% endfor %}
</div>
</div>
</div>
在 settings. 中退出
CKEDITOR_CONFIGS = {
'comment_ckeditor': {
'toolbar': 'custom',
'toolbar_custom': [['Bold', 'Italic', 'Underline', 'Strike', 'Subscript', 'Superscript'],
["TextColor", "BGColor", 'RemoveFormat'],
['NumberedList', 'BulletedList'],
['Link', 'Unlink'],
["Smiley", "SpecialChar", 'Blockquote'],
],
'width': 'auto',
'height': '180',
'tabSpaces': 4,
'removePlugins': 'elementspath',
'resize_enabled': False,
}
}
而后减少 blog.css 款式
div.django-ckeditor-widget {width: 100%;}
批改 blog.forms.py 中的 CommentFomr 类上面的 text 内容
text = forms.CharField(widget=CKEditorWidget(config_name='comment_ckeditor'),
error_messages={'required': '评论内容不能为空'})
给 comment/models.py 中减少袁磊,使其依照评论工夫倒序排列:
class Meta:
ordering = ['-comment_time']
正文完
发表至: javascript
2020-11-26