一、djangoAdmin和表结构
1.项目名称
python manage startapp web # 前端页面
python manage startapp repository # 只是数据库
python manage startapp backend # 后台管理
2.repository/models.py
from django.db import models # Create your models here. class UserInfo(models.Model):
nid = models.AutoField(primary_key=True)
username = models.CharField(max_length=32, unique=True)
password = models.CharField(max_length=32)
email = models.CharField(max_length=32, unique=True)
ctime = models.DateTimeField() class Meta:
verbose_name_plural = '用户表' # 在django中显示表名称 def __str__(self):
return self.username
# 显示字段对象名称 class NewsType(models.Model):
nid = models.AutoField(primary_key=True)
caption = models.CharField(max_length=32) class Meta:
verbose_name_plural = "新闻类型" def __str__(self):
return self.caption class News(models.Model):
nid = models.AutoField(primary_key=True)
user_info = models.ForeignKey('UserInfo')
news_type = models.ForeignKey('NewsType')
title = models.CharField(max_length=32, db_index=True)
url = models.CharField(max_length=128, null=True, blank=True)
content = models.CharField(max_length=50)
favor_count = models.IntegerField(default=0)
comment_count = models.IntegerField(default=0)
ctime = models.DateTimeField()
img = models.CharField(max_length=32, default="/static/images/1.jpg") class Meta:
verbose_name_plural = '新闻' def __str__(self):
return self.title class Favor(models.Model):
nid = models.AutoField(primary_key=True)
user_info = models.ForeignKey('UserInfo')
news = models.ForeignKey('News')
ctime = models.DateTimeField() def __str__(self):
return "{0}<{1}>".format(self.news.title, self.user_info.username) class Meta:
verbose_name_plural = '点赞记录'
unique_together = (
("user_info", "news"),
) class Comment(models.Model):
nid = models.AutoField(primary_key=True)
user_info = models.ForeignKey('UserInfo')
news = models.ForeignKey('News')
ctime = models.DateTimeField()
device = models.CharField(max_length=16, null=True, blank=True)
content = models.CharField(max_length=150)
reply_id = models.ForeignKey('Comment', related_name='b', null=True, blank=True) class Meta:
verbose_name_plural = '评论表'
3.repository/admin.py
from django.contrib import admin
from repository.models import * # Register your models here.
admin.site.register(UserInfo)
admin.site.register(Comment)
admin.site.register(Favor)
admin.site.register(News)
admin.site.register(NewsType)
4. python manage.py createsuperuser
5. settings.py 注册项目
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'repository',
]
6.python manage.py makemigrations
python manage.py migrate
7.http://127.0.0.1:8000/admin
8.备注:
允许为空:null=True,blank=True(djangoAdmin需要)
二、点赞
1.templates/index.html
<script src="/static/jquery.js"></script>
<script>
function doFavor(ths,nid) { if ($('#tl').attr('login') == "true"){
$.ajax({
url: '/do-favor/',
type: "GET",
data: {nid: nid},
dataType: 'JSON',
success:function (arg) {
if(arg.status == 1){
// -1
var favorCount = $(ths).find('.favor-count').text();
favorCount = parseInt(favorCount);
favorCount = favorCount -1;
$(ths).find('.favor-count').text(favorCount);
ZMM(ths,"-1"); }else if(arg.status == 2){
// +1
var favorCount = $(ths).find('.favor-count').text();
favorCount = parseInt(favorCount);
favorCount = favorCount + 1;
$(ths).find('.favor-count').text(favorCount);
ZMM(ths,"+1"); }else{
location.href = '/login/';
}
}
})
}else{
location.href = '/login/';
}
} function ZMM(ths,txt) {
var fontSize = 5;
var left = 5;
var top = 5;
var opacity = 1; var tag = document.createElement('span');
tag.innerHTML = txt;
tag.style.position = "absolute";
tag.style.fontSize = fontSize + 'px';
tag.style.left = left+ 'px';
tag.style.top = top+ 'px';
tag.style.opacity = opacity;
$(ths).append(tag); var obj = setInterval(function () {
fontSize = fontSize + 5;
left = left + 5;
top = top - 5;
opacity = opacity - 0.1;
tag.style.fontSize = fontSize + 'px';
tag.style.left = left+ 'px';
tag.style.top = top+ 'px';
tag.style.opacity = opacity;
if(left > 60){
clearInterval(obj);
tag.remove();
}
},100);
}
</script>
2.web/views.py
def do_favor(request):
"""
1. 获取新闻ID
2. 当前登录的用户ID
3. 在favor表中插入数据
4. 新闻表中的favor_count + 1
:param request:
:return:
"""
ret = {'status': 0, 'error': ''}
if request.session.get('is_login'):
news_id = request.GET.get('nid')
current_user_id = request.session['user_info']['user_id']
ct = models.Favor.objects.filter(user_info_id=current_user_id,news_id=news_id).count()
if ct:
models.Favor.objects.filter(user_info_id=current_user_id, news_id=news_id).delete()
news_obj = models.News.objects.filter(nid=news_id).first()
temp = news_obj.favor_count - 1
models.News.objects.filter(nid=news_id).update(favor_count=temp)
ret['status'] = 1
else:
models.Favor.objects.create(user_info_id=current_user_id,news_id=news_id)
news_obj = models.News.objects.filter(nid=news_id).first()
temp = news_obj.favor_count + 1
models.News.objects.filter(nid=news_id).update(favor_count=temp)
ret['status'] = 2
return HttpResponse(json.dumps(ret))
三、评论区
注意:1张表自关联,使用了replay_id,通过python字典,列表数据类型的引用特性处理。需要使用迭代方式处理,最后返回给前端。其实后端不应该处理标签,应该放在前端处理。
1.web/views.py
def comment(request):
# 模拟数据
# comment_list = [
# {'id': 1, 'news_id': 1, 'user_id': 10, 'content': "写的什么玩意呀", 'reply_id': None},
# {'id': 2, 'news_id': 1, 'user_id': 11, 'content': "还真不是玩意 ", 'reply_id': 1},
# {'id': 3, 'news_id': 1, 'user_id': 12, 'content': "写的真好 ", 'reply_id': 1},
# {'id': 4, 'news_id': 1, 'user_id': 11, 'content': "写的真好 ", 'reply_id': 3},
# {'id': 5, 'news_id': 1, 'user_id': 19, 'content': "balabala ", 'reply_id': None},
# {'id': 6, 'news_id': 1, 'user_id': 11, 'content': "你可以趣事了 ", 'reply_id': 2},
# {'id': 7, 'news_id': 1, 'user_id': 11, 'content': "号的", 'reply_id': 6},
# ]
comment_list = [] new_nid = request.GET.get('nid')
obj = News.objects.filter(nid=new_nid)[0]
for row in obj.comment_set.values():
comment_list.append(row) # 一.变成字典,id为K, 字典为V
comment_dict = {}
for row in comment_list:
row['child'] = [] # 增加空字段
comment_dict[row['nid']] = row # ID做为K,行数据做V # 二.找到replay_id后,加到后面的child, python数据类型,除了int,str其它都是引用.
for row in comment_list:
if row['reply_id_id']:
replay_id = row['reply_id_id']
comment_dict[replay_id]['child'].append(row) # 三.这样回复链就做好了.
commen_reuslt = {}
for k, v in comment_dict.items():
if v['reply_id_id'] == None:
commen_reuslt[k] = v commen_reuslt = create_html(commen_reuslt)
return HttpResponse(json.dumps(commen_reuslt, ensure_ascii=False)) def create_child_node(child_comment):
prev = """
<div class="comment1">
<div class="content1">
"""
for child in child_comment:
tpl = '<div class="item">%s</div>'
content = tpl % child['content']
prev = prev + content
if child['child']:
# 有子评论
node = create_child_node(child['child'])
prev = prev + node end = """
</div>
</div>
"""
return prev + end def create_html(comment_result):
prev = """
<div class="comment1">
<div class="content1">
""" for k,v in comment_result.items():
tpl = '<div class="item">%s</div>'
content = tpl %v['content']
prev = prev + content
if v['child']:
# 有子评论
node = create_child_node(v['child'])
prev = prev + node end = """
</div>
</div>
"""
return prev + end
2.templates/index.html
<div id="comment_area_{{item.nid}}" class="comment-box-area hide" >
<div class="pinglun arrow"></div>
<a class="pinglun close-comt" title="关闭" href="javascript:void(0);"></a>
<div class="corner comment-box clearfix" >
<div class="loading-ico loading-ico-top" style="margin-left:230px;">加载中,请稍候...</div>
<div class="comment-box-top " >
<div class="tip-1">最热评论(<span>{{item.8}}</span>)</div>
<div class="tip-2">
<a href="#" target="_blank">
<em class="pinglun em1"></em>
<span>去评论页面</span>
</a>
</div>
</div>
<ul id="comment_list_{{item.nid}}" class="filetree comment-list-top-2 treeview "> </ul> function ToggleCommentArea(nid){
var $comment_area = $("#comment_area_" + nid);
if($comment_area.hasClass('hide')){
$comment_area.removeClass('hide');
var $comment_list = $("#comment_list_" + nid);
$.ajax({
url: '/comment/',
type: 'GET',
data: {nid: nid},
dataType:"JSON",
success: function(arg){
$comment_list.empty();
$comment_list.append(arg);
var $loading = $comment_area.find('.comment-box').children().first();
$loading.addClass('hide');
$loading.siblings().removeClass('hide');
}
})
}else{
$comment_area.addClass('hide');
}
}
四、kingeditor