一、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

http://www.cnblogs.com/wupeiqi/articles/6307554.html

python16_day20【Django_继续抽屉项目】的更多相关文章

  1. python16_day19【Django_抽屉项目】

    补充ORM块: 1.select_related()  # 解决:当有外健,规避多决查询,使用了join. 多次查询变成一次查询 例:UserInfo.objects.all().select_rel ...

  2. Django_博客项目 引入外部js文件内含模板语法无法正确获取值得说明和处理

    问题描述 : 项目中若存在对一段js代码复用多次的时候, 通常将此段代码移动到一个单独的静态文件中在被使用的地方利用 script 标签的 src 属性进行外部调用 但是如果此文件中存在使用 HTML ...

  3. Django_博客项目 注册用户引发 ValueError: The given username must be set

    博客项目中 注册功能在ajax 提交数据时 报错 ValueError: The given username must be set 锁定到错误点为 判定为是无法获取到 username 字段 那先 ...

  4. django 表结构

    django 表结构 一:查看orm写的sq语句:如果对某个语句不清楚的话可以调用queryset的的query方法来查看sql. 1 obj=Hostinfo.objects.filter(id=v ...

  5. tornado web高级开发项目之抽屉官网的页面登陆验证、form验证、点赞、评论、文章分页处理、发送邮箱验证码、登陆验证码、注册、发布文章、上传图片

    本博文将一步步带领你实现抽屉官网的各种功能:包括登陆.注册.发送邮箱验证码.登陆验证码.页面登陆验证.发布文章.上传图片.form验证.点赞.评论.文章分页处理以及基于tornado的后端和ajax的 ...

  6. Django_项目初始化

    如何初始Django运行环境? 1. 安装python 2. 创建Django项目专用的虚拟环境 http://www.cnblogs.com/2bjiujiu/p/7365876.html 3.进入 ...

  7. Django_创建项目

    安装django pip install Django 将下面路径添加到系统环境变量的path中 C:\Users\12978\AppData\Local\Programs\Python\Python ...

  8. Python之路【第二十篇】:python项目之旧版抽屉新热榜

    旧版抽屉新热榜 代码如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset=& ...

  9. Django_项目开始

    如何初始Django运行环境? 1. 安装python 2. 创建Django项目专用的虚拟环境 http://www.cnblogs.com/2bjiujiu/p/7365876.html 3.进入 ...

随机推荐

  1. 阿里Java开发手冊之编程规约

    对于程序猿来说,编程规范能够养成良好的编程习惯,提高代码质量,减少沟通成本.就在2月9号,阿里出了一份Java开发手冊(正式版),分为编程规约.异常日志.MySQL规约,project规约.安全规约五 ...

  2. RabbitMQ之Exchange-4

    RabbitMQ消息模型的核心思想是生产者不会将消息直接发送给队列.生产者通常不知道消息将会被哪些消费者接收,按照刚开始里介绍的rabbitMQ中所画的,生产者不是直接将消息发送给Queue么认识会交 ...

  3. ASP.NET MVC5 新特性:Attribute路由使用详解

    1.什么是Attribute路由?怎么样启用Attribute路由? 微软在 ASP.NET MVC5 中引入了一种新型路由:Attribute路由,顾名思义,Attribute路由是通过Attrib ...

  4. Spring.NET学习笔记——目录(原)

    目录 前言 Spring.NET学习笔记——前言 第一阶段:控制反转与依赖注入IoC&DI Spring.NET学习笔记1——控制反转(基础篇) Level 200 Spring.NET学习笔 ...

  5. 调用组件的C++代码

    #include<stdio.h>#include "LJSummary.h"#include<iostream>int main(void){ print ...

  6. JZOJ.5305【NOIP2017模拟8.18】C

    Description

  7. powerdesigner 导入SQL脚本生成模型

  8. 面试之一:CMS收集器整理

      CMS收集器整理 @white 基本说明: 目标:获取最短回收停顿时间 算法:标记-清除算法 线程:并发 步骤: 初始标记:(会STP) 标记 GC Roots 能直接关联到的对象,速度很快 并发 ...

  9. Spring boot:logback文件配置

    resources文件夹下:新建logback-spring.xml文件. 文件内容like: <?xml version="1.0" encoding="UTF- ...

  10. CodeForces 732B Cormen — The Best Friend Of a Man

    B. Cormen - The Best Friend Of a Man time limit per test 1 second memory limit per test 256 megabyte ...