python16_day20【Django_继续抽屉项目】
一、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
1 from django.contrib import admin 2 from repository.models import * 3 4 # Register your models here. 5 admin.site.register(UserInfo) 6 admin.site.register(Comment) 7 admin.site.register(Favor) 8 admin.site.register(News) 9 admin.site.register(NewsType)
4. python manage.py createsuperuser
5. settings.py 注册项目
1 INSTALLED_APPS = [ 2 'django.contrib.admin', 3 'django.contrib.auth', 4 'django.contrib.contenttypes', 5 'django.contrib.sessions', 6 'django.contrib.messages', 7 'django.contrib.staticfiles', 8 'repository', 9 ]
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
1 def do_favor(request): 2 """ 3 1. 获取新闻ID 4 2. 当前登录的用户ID 5 3. 在favor表中插入数据 6 4. 新闻表中的favor_count + 1 7 :param request: 8 :return: 9 """ 10 ret = {'status': 0, 'error': ''} 11 if request.session.get('is_login'): 12 news_id = request.GET.get('nid') 13 current_user_id = request.session['user_info']['user_id'] 14 ct = models.Favor.objects.filter(user_info_id=current_user_id,news_id=news_id).count() 15 if ct: 16 models.Favor.objects.filter(user_info_id=current_user_id, news_id=news_id).delete() 17 news_obj = models.News.objects.filter(nid=news_id).first() 18 temp = news_obj.favor_count - 1 19 models.News.objects.filter(nid=news_id).update(favor_count=temp) 20 ret['status'] = 1 21 else: 22 models.Favor.objects.create(user_info_id=current_user_id,news_id=news_id) 23 news_obj = models.News.objects.filter(nid=news_id).first() 24 temp = news_obj.favor_count + 1 25 models.News.objects.filter(nid=news_id).update(favor_count=temp) 26 ret['status'] = 2 27 return HttpResponse(json.dumps(ret))
三、评论区
注意:1张表自关联,使用了replay_id,通过python字典,列表数据类型的引用特性处理。需要使用迭代方式处理,最后返回给前端。其实后端不应该处理标签,应该放在前端处理。
1.web/views.py
1 def comment(request): 2 # 模拟数据 3 # comment_list = [ 4 # {'id': 1, 'news_id': 1, 'user_id': 10, 'content': "写的什么玩意呀", 'reply_id': None}, 5 # {'id': 2, 'news_id': 1, 'user_id': 11, 'content': "还真不是玩意 ", 'reply_id': 1}, 6 # {'id': 3, 'news_id': 1, 'user_id': 12, 'content': "写的真好 ", 'reply_id': 1}, 7 # {'id': 4, 'news_id': 1, 'user_id': 11, 'content': "写的真好 ", 'reply_id': 3}, 8 # {'id': 5, 'news_id': 1, 'user_id': 19, 'content': "balabala ", 'reply_id': None}, 9 # {'id': 6, 'news_id': 1, 'user_id': 11, 'content': "你可以趣事了 ", 'reply_id': 2}, 10 # {'id': 7, 'news_id': 1, 'user_id': 11, 'content': "号的", 'reply_id': 6}, 11 # ] 12 comment_list = [] 13 14 new_nid = request.GET.get('nid') 15 obj = News.objects.filter(nid=new_nid)[0] 16 for row in obj.comment_set.values(): 17 comment_list.append(row) 18 19 # 一.变成字典,id为K, 字典为V 20 comment_dict = {} 21 for row in comment_list: 22 row['child'] = [] # 增加空字段 23 comment_dict[row['nid']] = row # ID做为K,行数据做V 24 25 # 二.找到replay_id后,加到后面的child, python数据类型,除了int,str其它都是引用. 26 for row in comment_list: 27 if row['reply_id_id']: 28 replay_id = row['reply_id_id'] 29 comment_dict[replay_id]['child'].append(row) 30 31 # 三.这样回复链就做好了. 32 commen_reuslt = {} 33 for k, v in comment_dict.items(): 34 if v['reply_id_id'] == None: 35 commen_reuslt[k] = v 36 37 commen_reuslt = create_html(commen_reuslt) 38 return HttpResponse(json.dumps(commen_reuslt, ensure_ascii=False)) 39 40 41 def create_child_node(child_comment): 42 prev = """ 43 <div class="comment1"> 44 <div class="content1"> 45 """ 46 for child in child_comment: 47 tpl = '<div class="item">%s</div>' 48 content = tpl % child['content'] 49 prev = prev + content 50 if child['child']: 51 # 有子评论 52 node = create_child_node(child['child']) 53 prev = prev + node 54 55 end = """ 56 </div> 57 </div> 58 """ 59 return prev + end 60 61 62 def create_html(comment_result): 63 prev = """ 64 <div class="comment1"> 65 <div class="content1"> 66 """ 67 68 for k,v in comment_result.items(): 69 tpl = '<div class="item">%s</div>' 70 content = tpl %v['content'] 71 prev = prev + content 72 if v['child']: 73 # 有子评论 74 node = create_child_node(v['child']) 75 prev = prev + node 76 77 end = """ 78 </div> 79 </div> 80 """ 81 return prev + end
2.templates/index.html
1 2 3 <div id="comment_area_{{item.nid}}" class="comment-box-area hide" > 4 <div class="pinglun arrow"></div> 5 <a class="pinglun close-comt" title="关闭" href="javascript:void(0);"></a> 6 <div class="corner comment-box clearfix" > 7 <div class="loading-ico loading-ico-top" style="margin-left:230px;">加载中,请稍候...</div> 8 <div class="comment-box-top " > 9 <div class="tip-1">最热评论(<span>{{item.8}}</span>)</div> 10 <div class="tip-2"> 11 <a href="#" target="_blank"> 12 <em class="pinglun em1"></em> 13 <span>去评论页面</span> 14 </a> 15 </div> 16 </div> 17 <ul id="comment_list_{{item.nid}}" class="filetree comment-list-top-2 treeview "> 18 19 </ul> 20 21 22 23 24 function ToggleCommentArea(nid){ 25 var $comment_area = $("#comment_area_" + nid); 26 if($comment_area.hasClass('hide')){ 27 $comment_area.removeClass('hide'); 28 var $comment_list = $("#comment_list_" + nid); 29 $.ajax({ 30 url: '/comment/', 31 type: 'GET', 32 data: {nid: nid}, 33 dataType:"JSON", 34 success: function(arg){ 35 $comment_list.empty(); 36 $comment_list.append(arg); 37 var $loading = $comment_area.find('.comment-box').children().first(); 38 $loading.addClass('hide'); 39 $loading.siblings().removeClass('hide'); 40 } 41 }) 42 }else{ 43 $comment_area.addClass('hide'); 44 } 45 }
四、kingeditor