编辑功能使用到了ckeditor的MathJax组件。ajax提交评论可以不用刷新浏览器。

1、变化的部分

aaarticlea/png;base64,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" alt="" width="323" height="717" />

2、上代码:

ul.blog-types,ul.blog-dates {
list-style-type: none;
} div.blog:not(:last-child) {
margin-bottom: 2em;
padding-bottom: 1em;
border-bottom: 1px solid #eee;
} div.blog h3 {
margin-top: 0.5em;
} div.blog-info p {
margin-bottom:;
}
div.blog-info p span{
margin-right: 10px;
} div.blog-info-description {
list-style-type: none;
margin-bottom: 1em;
} ul.blog-info-description li {
display: inline-block;
margin-right: 1em;
} div.paginator {
text-align: center;
} div.container {
max-width: 80%;
} div.comment-area{
margin-top: 2em;
} h3.comment-area-title{
border-bottom: 1px solid #ccc;
padding-bottom: 0.4em;
} div.django-ckeditor-widget {
width: 100%;
}

blog.css

{# 引用模板 #}
{% extends 'base.html' %}
{% load staticfiles %} {% block header_extends %}
<link rel="stylesheet" href="{% static 'blog/blog.css' %}">
{# 处理公式 #}
<script src='https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML'
async></script>
<script type="text/javascript" src="{% static "ckeditor/ckeditor-init.js" %}"></script>
<script type="text/javascript" src="{% static "ckeditor/ckeditor/ckeditor.js" %}"></script>
{% endblock %} {# 标题 #}
{% block title %}
{{ blog.title }}
{% endblock %} {# 内容#}
{% block content %}
<div class="container">
<div class="row">
<div class="col-10 offset-1">
<ul class="blog-info-description">
<h3>{{ blog.title }}</h3>
<li>作者:{{ blog.author }}</li>
{# 时间过滤器让时间按照自己需要的格式过滤 #}
<li>发布日期:{{ blog.created_time|date:"Y-m-d H:i:s" }}</li>
<li>分类:
<a href="{% url 'blogs_with_type' blog.blog_type.pk %}">
{{ blog.blog_type }}
</a>
</li>
<li>阅读({{ blog.get_read_num }})</li>
</ul>
<p class="blog-content">{{ blog.content|safe }}</p> <p>上一篇:
{% if previous_blog %}
<a href="{% url 'blog_detail' previous_blog.pk %}">{{ previous_blog.title }}</a>
{% else %}
<span>没有了</span>
{% endif %}
</p>
<p>下一篇:
{% if next_blog %}
<a href="{% url 'blog_detail' next_blog.pk %}">{{ next_blog.title }}</a>
{% else %}
<span>没有了</span>
{% endif %}
</p>
</div>
</div>
<div class="row">
<div class="col-10 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">
{% csrf_token %}
<label for="form-control">{{ user.username }},欢迎评论~</label>
{% for field in comment_form %}
{{ field }}
{% endfor %}
<span id="comment-error" class="text-danger float-left"></span>
<input type="submit" value="评论" class="btn btn-primary float-right">
</form>
{% else %}
您尚未登录,登录之后方可评论
{# 提交登录的时候带上从哪里访问的路径 #}
<a class="btn btn-primary" href="{% url 'login' %}?from={{ request.get_full_path }}">登录</a>
<span> or </span>
<a class="btn-danger btn" 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 js %}
<script>
$('#comment-form').submit(function () {
// 获取错误框
let comment_error = $('#comment-error');
comment_error.text(''); // 更新数据到textarea
CKEDITOR.instances['id_text'].updateElement();
let comment_text = CKEDITOR.instances['id_text'].document.getBody().getText().trim();
// 判断是否为空
if (!(CKEDITOR.instances['id_text'].document.getBody().find('img')['$'].length !== 0 || comment_text !== '')) {
// 显示错误信息
comment_error.text('评论内容不能为空');
return false;
}
//异步提交
$.ajax({
url: "{% url 'update_comment' %}",
type: 'POST',
data: $(this).serialize(),// 序列化表单值
cache: false, // 关闭缓存
success: function (data) { if (data['status'] === 'SUCCESS') {
console.log(data);
// 插入数据
// es6写法
let 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> <script>
$(".nav-blog").addClass("active").siblings().removeClass("active");
</script>
{% endblock %}

blog_detail.html

{# 引用模板 #}
{% extends 'base.html' %}
{% load staticfiles %} {% block header_extends %}
<link rel="stylesheet" href="{% static 'blog/blog.css' %}">
{# 处理公式 #}
<script src='https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML'
async></script>
<script type="text/javascript" src="{% static "ckeditor/ckeditor-init.js" %}"></script>
<script type="text/javascript" src="{% static "ckeditor/ckeditor/ckeditor.js" %}"></script>
{% endblock %} {# 标题 #}
{% block title %}
{{ blog.title }}
{% endblock %} {# 内容#}
{% block content %}
<div class="container">
<div class="row">
<div class="col-10 offset-1">
<ul class="blog-info-description">
<h3>{{ blog.title }}</h3>
<li>作者:{{ blog.author }}</li>
{# 时间过滤器让时间按照自己需要的格式过滤 #}
<li>发布日期:{{ blog.created_time|date:"Y-m-d H:i:s" }}</li>
<li>分类:
<a href="{% url 'blogs_with_type' blog.blog_type.pk %}">
{{ blog.blog_type }}
</a>
</li>
<li>阅读({{ blog.get_read_num }})</li>
</ul>
<p class="blog-content">{{ blog.content|safe }}</p> <p>上一篇:
{% if previous_blog %}
<a href="{% url 'blog_detail' previous_blog.pk %}">{{ previous_blog.title }}</a>
{% else %}
<span>没有了</span>
{% endif %}
</p>
<p>下一篇:
{% if next_blog %}
<a href="{% url 'blog_detail' next_blog.pk %}">{{ next_blog.title }}</a>
{% else %}
<span>没有了</span>
{% endif %}
</p>
</div>
</div>
<div class="row">
<div class="col-10 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">
{% csrf_token %}
<label for="form-control">{{ user.username }},欢迎评论~</label>
{% for field in comment_form %}
{{ field }}
{% endfor %}
<span id="comment-error" class="text-danger float-left"></span>
<input type="submit" value="评论" class="btn btn-primary float-right">
</form>
{% else %}
您尚未登录,登录之后方可评论
{# 提交登录的时候带上从哪里访问的路径 #}
<a class="btn btn-primary" href="{% url 'login' %}?from={{ request.get_full_path }}">登录</a>
<span> or </span>
<a class="btn-danger btn" 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 js %}
<script>
$('#comment-form').submit(function () {
// 获取错误框
let comment_error = $('#comment-error');
comment_error.text(''); // 更新数据到textarea
CKEDITOR.instances['id_text'].updateElement();
let comment_text = CKEDITOR.instances['id_text'].document.getBody().getText().trim();
// 判断是否为空
if (!(CKEDITOR.instances['id_text'].document.getBody().find('img')['$'].length !== 0 || comment_text !== '')) {
// 显示错误信息
comment_error.text('评论内容不能为空');
return false;
}
//异步提交
$.ajax({
url: "{% url 'update_comment' %}",
type: 'POST',
data: $(this).serialize(),// 序列化表单值
cache: false, // 关闭缓存
success: function (data) { if (data['status'] === 'SUCCESS') {
console.log(data);
// 插入数据
// es6写法
let 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> <script>
$(".nav-blog").addClass("active").siblings().removeClass("active");
</script>
{% endblock %}

blog下的views.py

# -*- coding: utf-8 -*-
# @Time : 18-11-20 下午10:47
# @Author : Felix Wang 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().__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 as e:
raise forms.ValidationError('评论对象不存在') return self.cleaned_data

comment下的forms.py

from django.shortcuts import render, reverse, redirect
from django.http import JsonResponse
from .models import Comment
from django.contrib.contenttypes.models import ContentType
from .forms import CommentForm
import re
import copy def update_commit(requests):
comment_form = CommentForm(requests.POST, user=requests.user)
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',
'username': comment.user.username,
'comment_time': comment.comment_time.strftime('%Y-%m-%d %H:%M:%S'),
'text': comment.text.strip(),
}
else:
data = {
'status': 'ERROR',
'message': list(comment_form.errors.values())[0][0],
}
return JsonResponse(data)

comment下的biews.py

# -*- coding: utf-8 -*-
# @Time : 18-11-20 下午8:10
# @Author : Felix Wang from django import forms
from django.contrib import auth
from django.contrib.auth.models import User class LoginForm(forms.Form):
username = forms.CharField(label='用户名', required=True,
widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': '请输入用户名'}))
# widget指定input标签类型
password = forms.CharField(label='密码',
widget=forms.PasswordInput(attrs={'class': 'form-control', 'placeholder': '请输入密码'})) def clean(self): # 验证数据
username = self.cleaned_data['username']
password = self.cleaned_data['password']
user = auth.authenticate(username=username, password=password)
if user is None:
raise forms.ValidationError('用户名或密码错误')
self.cleaned_data['user'] = user # 将验证过的user放入clean_data
return self.cleaned_data class RegisterForm(forms.Form):
# 用户名字段
username = forms.CharField(label='用户名',
max_length=30,
min_length=3,
required=True,
widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': '请输入用户名'}))
# 邮箱字段
email = forms.EmailField(label='邮箱',
min_length=3,
required=True,
widget=forms.EmailInput(attrs={'class': 'form-control', 'placeholder': '请输入邮箱'}))
# 密码字段
password = forms.CharField(label='密码',
min_length=6,
required=True,
widget=forms.PasswordInput(
attrs={'class': 'form-control', 'placeholder': '请输入密码'}))
# 再次输入密码
password_again = forms.CharField(label='确认密码',
min_length=6,
required=True,
widget=forms.PasswordInput(
attrs={'class': 'form-control', 'placeholder': '请再输入一次密码'})) def clean_username(self):
username = self.cleaned_data['username']
if User.objects.filter(username=username).exists():
raise forms.ValidationError('用户名已存在')
return username def clean_email(self):
email = self.cleaned_data['email']
if User.objects.filter(email=email).exists():
raise forms.ValidationError('邮箱已存在') return email def clean_password_again(self):
password = self.cleaned_data['password']
password_again = self.cleaned_data['password_again']
if password != password_again:
raise forms.ValidationError('两次输入的密码不一致')
return password_again

myblog下的forms.py

"""
Django settings for myblog project. Generated by 'django-admin startproject' using Django 2.1.3. For more information on this file, see
https://docs.djangoproject.com/en/2.1/topics/settings/ For the full list of settings and their values, see
https://docs.djangoproject.com/en/2.1/ref/settings/
""" import os # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/2.1/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'ea+kzo_5k^6r7micfg@lar1(rfdc08@b4*+w5d11=0mp1p5ngr' # SECURITY WARNING: don't run with debug turned on in production!2.
DEBUG = True ALLOWED_HOSTS = ['*'] # Application definition INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'ckeditor',
'ckeditor_uploader',
'blog.apps.BlogConfig', # 将自己创建的app添加到设置中
'read_statistics.apps.ReadStatisticsConfig', # 注册阅读统计app
'comment.apps.CommentConfig', # 注册评论 ] MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'blog.middleware.mymiddleware.My404', # 添加自己的中间件
] ROOT_URLCONF = 'myblog.urls' TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
os.path.join(BASE_DIR, 'templates'),
],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
] WSGI_APPLICATION = 'myblog.wsgi.application' # Database
# https://docs.djangoproject.com/en/2.1/ref/settings/#databases DATABASES = {
# 'default': {
# 'ENGINE': 'django.db.backends.sqlite3',
# 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
# }
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'myblogs', # 要连接的数据库,连接前需要创建好
'USER': 'root', # 连接数据库的用户名
'PASSWORD': 'felixwang', # 连接数据库的密码
'HOST': '127.0.0.1', # 连接主机,默认本级
'PORT': 3306 # 端口 默认3306
}
} # Password validation
# https://docs.djangoproject.com/en/2.1/ref/settings/#auth-password-validators AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
] # Internationalization
# https://docs.djangoproject.com/en/2.1/topics/i18n/ # LANGUAGE_CODE = 'en-us'
# 语言
LANGUAGE_CODE = 'zh-hans' # TIME_ZONE = 'UTC'
# 时区
TIME_ZONE = 'Asia/Shanghai' USE_I18N = True USE_L10N = True # 不考虑时区
USE_TZ = False # Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.1/howto/static-files/ STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static")
] # media
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media') # 配置ckeditor
CKEDITOR_UPLOAD_PATH = 'upload/' # 自定义参数
EACH_PAGE_BLOGS_NUMBER = 7 # 设置数据库缓存
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
'LOCATION': 'my_read_num_cache_table',
}
} # ckeditor 代码高亮,以及公式
CKEDITOR_CONFIGS = {
'default': {
'skin': 'moono',
'tabSpaces': 4,
'mathJaxLib': 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML',
'toolbar': (
['div', 'Source', '-', 'Save', 'NewPage', 'Preview', '-', 'Templates'],
['Cut', 'Copy', 'Paste', 'PasteText', 'PasteFromWord', '-', 'Print',
'SpellChecker', 'Scayt'],
['Undo', 'Redo', '-', 'Find', 'Replace', '-', 'SelectAll', 'RemoveFormat',
'-', 'Maximize', 'ShowBlocks', '-', "CodeSnippet", 'Mathjax', 'Subscript',
'Superscript'],
['Form', 'Checkbox', 'Radio', 'TextField', 'Textarea', 'Select', 'Button',
'ImageButton', 'HiddenField'],
['Bold', 'Italic', 'Underline', 'Strike', '-'],
['NumberedList', 'BulletedList', '-', 'Outdent', 'Indent', 'Blockquote'],
['JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock'],
['Link', 'Unlink', 'Anchor'],
['Image', 'Flash', 'Table', 'HorizontalRule', 'Smiley', 'SpecialChar',
'PageBreak'], ['Styles', 'Format', 'Font', 'FontSize'],
['TextColor', 'BGColor'],),
'extraPlugins': ','.join([
'codesnippet',
'mathjax',
'dialog',
'dialogui',
'lineutils',
]),
},
'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': '',
'tabSpace': 4,
'removePlugins': 'elementspath',
'resize_enabled': False,
}
}

settings.py

搭建自己的博客(二十二):通过ajax提交评论信息,并增加公式编辑功能的更多相关文章

  1. Django 系列博客(十二)

    Django 系列博客(十二) 前言 本篇博客继续介绍 Django 中的查询,分别为聚合查询和分组查询,以及 F 和 Q 查询. 聚合查询 语法:aggregate(*args, **kwargs) ...

  2. github+hexo搭建自己的博客网站(二)更换主题yilia

    开始更换主题,hexo默认的主题是landscape,可以更换为其他的主题yilia主题 详细的可以查看hexo博客的演示:saucxs.github.io 可以查看在github上生成的静态文件:h ...

  3. 自然语言交流系统 phxnet团队 创新实训 项目博客 (十二)

    关于情感词典的学习总结: 情感倾向可认为是主体对某一客体主观存在的内心喜恶,内在评价的一种倾向.它由两个方面来衡量:一个情感倾向方向,一个是情感倾向度. 情感倾向方向也称为情感极性.在微博中,可以理解 ...

  4. 自然语言交流系统 phxnet团队 创新实训 个人博客 (十二)

    在本项目中关于天空盒子的使用的配置方法: 给场景添加天空盒  第二种方式   在菜单栏中选择:Edit->Render Setting,在保证不在选择场景中其它文件的前提下,Inspector面 ...

  5. github+hexo搭建自己的博客网站(六)进阶配置(搜索引擎收录,优化你的url)

    详细的可以查看hexo博客的演示:https://saucxs.github.io/ 绑定了域名: http://www.chengxinsong.cn hexo+github博客网站源码(可以clo ...

  6. github+hexo搭建自己的博客网站(七)注意事项(避免read.me,CNAME文件的覆盖,手动改github page的域名)

    详细的可以查看hexo博客的演示:https://saucxs.github.io/ 绑定域名可以查看:http://www.chengxinsong.cn 可以查看在github上生成的静态文件(如 ...

  7. 从入门到放弃,.net构建博客系统(二):依赖注入

    文章目录:<从入门到放弃,.net构建博客系统> 从入门到放弃,.net构建博客系统(一):系统构建 从入门到放弃,.net构建博客系统(二):依赖注入 上一篇中有讲到项目启动时会进行io ...

  8. 一步步搭建自己的博客 .NET版(2、评论功能)

    前言 这次开发的博客主要功能或特点:    第一:可以兼容各终端,特别是手机端.    第二:到时会用到大量html5,炫啊.    第三:导入博客园的精华文章,并做分类.(不要封我)    第四:做 ...

  9. 基于hexo+github搭建一个独立博客

    一直听说用hexo搭建一个拥有自己域名的博客是很酷炫的事情~,在这十一花上半个小时整个hexo博客岂不美哉. 使用Hexo吸引我的是,其简单优雅, 而且风格多变, 适合程序员搭建个人博客,而且支持多平 ...

随机推荐

  1. Vue使用指南(二)

    '''1.指令 ***** 文本指令 属性指令 方法(事件)指令 表单指令 条件指令 循环指令 2.组件 *** 局部组件 全局组件 父子组件间的交互''' 文件指令 <body> < ...

  2. js中__proto__和prototype的区别和关系?(转)

    转自知乎:https://www.zhihu.com/question/34183746

  3. IEEE754浮点数

    前言 Go语言之父Rob Pike大神曾吐槽:不能掌握正则表达式或浮点数就不配当码农! You should not be permitted to write production code if ...

  4. 在论坛中出现的比较难的sql问题:29(row_number函数 组内某列的值连续出现3次标记出来)

    原文:在论坛中出现的比较难的sql问题:29(row_number函数 组内某列的值连续出现3次标记出来) 在论坛中,遇到了不少比较难的sql问题,虽然自己都能解决,但发现过几天后,就记不起来了,也忘 ...

  5. SQL case when 遇到null值

    case  when f.FPH is  NULL then a.HSJE else f.KPHSJE  end    yes case f.FPH  when   NULL then a.HSJE ...

  6. SQL查看数据库中每张表的数据量和总数据量

    查看所有表对应的数据量 SELECT a.name AS 表名, MAX(b.rows) AS 记录条数 FROM sys.sysobjects AS a INNER JOIN sys.sysinde ...

  7. 元素的colspan和rowspan

    colspan和rowspan这两个属性用于创建特殊的表格. colspan用来指定单元格横向跨越的列数:colspan就是合并列的,colspan=2就是合并两列. rowspan用来指定单元格纵向 ...

  8. 字节数组(byte[])与16进制字符串转换

    /// <summary> /// 转换扩展类 /// </summary> public static class ConvertExtend { /// <summa ...

  9. css 点击样式,水波纹(记录备用)

    <!DOCTYPE html><html lang="en"> <head> <meta charset="UTF-8" ...

  10. Spring/Spring Boot整合Weblogic JMS实战

    本文主要介绍weblogic jms的配置,包括JMS 服务器和JMS 模块(连接工厂.队列.远程 SAF 上下文.SAF 导入目的地.SAF 错误处理)的配置:并在Spring/Spring Boo ...