指标成果:
html的表单变成django_form
在comment中创立forms.py文件,编写代码:
from django import formsfrom django.contrib.contenttypes.models import ContentTypefrom django.db.models import ObjectDoesNotExistfrom ckeditor.widgets import CKEditorWidgetclass 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, redirectfrom django.contrib.contenttypes.models import ContentTypefrom django.urls import reversefrom django.http import JsonResponsefrom .models import Commentfrom .forms import CommentFormdef 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']