多人博客项目构建过程(三)

博文相关接口

功能分析

创建博文应用

 

模型

#在post/models.py中
from django.db import models
from user.models import User
# Create your models here.
class Post(models.Model):
    class Meta:
        db_table = 'post'
    id = models.AutoField(primary_key=True)
    title = models.CharField(max_length=256,null=False)
    postdate = models.DateTimeField(null=False)
    author = models.ForeignKey(User)#指定外键,migrate会生成author_id字段
    # self.content可以访问Content实例,其内容是self.content.content

    def __repr__(self):
        return '<Post {} {} {} {}>'.format(
            self.id,self.title,self.author,self.content
            #同上 self.id,self.title,self.author_id,self.content
        )

    __str__ = __repr__

#MySQL 表的一对一、一对多、多对多问题参考:https://www.cnblogs.com/Camiluo/p/10615065.html
class Content(models.Model):
    class Meta:
        db_table = 'content'
    #没有主键,会自动创建一个自增主键
    post = models.OneToOneField(Post,to_field=id)#一对一,这边会有一个外键引用post中的主键id,可省略不写
    content = models.TextField(null=False)

    def __repr__(self):
        return '<Content {} {}>'.format(self.post.id,self.content[:20])

    __str__ = __repr__

路由

全局设置

#在blog/urls.py中
from django.conf.urls import include
urlpatterns = [
    url(r'^$', admin.site.urls),
    url(r'^admin/', admin.site.urls),
    url(r'^index/',index),
    # url(r'^testfor/',testfor),
    url(r'^user/',include('user.urls'))#多级路由
    url(r'^post/',include('post.urls'))#多级路由
]

#post/urls.py
from django.conf.urls import url
from .views import pub,get,getall#,testMiddle


urlpatterns = [
    url(r'^pub',pub),
    url(r'^(d+)$',get),#给get传入一个参数str类型
    url(r'^$',getall),
]

pub接口实现

#post/urls.py
from django.http import HttpRequest,HttpResponse,JsonResponse
from django.http import HttpResponseBadRequest,HttpResponseNotFound
from user.views import authenticate
from user.models import User
import simplejson
import datetime
from .models import Post,Content

# Create your views here.
@authenticate
def pub(request:HttpRequest):
    post = Post()
    content = Content()
    try:
        payload = simplejson.loads(request.body)
        post.title = payload['title']
        # post.author = User(id=request.user.id)#user是在验证身份的时候注入的
        post.author = request.user #user是在验证身份的时候注入的
        post.postdate = datetime.datetime.now(
            datetime.timezone(datetime.timedelta(hours=8))
        )
        post.save()#获取一个post id

        content.content = payload['content']
        content.post = post#

        content.save()

        return JsonResponse({
            'post_id':post.id
        })
    except Exception as e:
        print(e)
        return HttpResponseBadRequest()

get接口实现

 

#post/views.py
def get(request:HttpRequest,id):#分组捕获传入
    try:
        id = int(id)
        post = Post.objects.get(pk=id)
        print(post,'__________')
        if post:
            return JsonResponse({
                'post':{
                    'post_id':post.id,
                    'title':post.title,
                    'author':post.author_id,#post.author.id
                    'postdate':post.postdate.timestamp(),
                    'content':post.content.content
                }
            })
        #get保证必须只有一条记录,否则抛出异常
    except Exception as e:
        print(e)
        return HttpResponseNotFound()

getall接口实现

 

#在post/views.py中
def getall(request:HttpRequest):
    try:#页码
        page = int(request.GET.get('page',1))
        page = page if page > 0 else 1
    except:
        page = 1

    try:#页码行数
        #注意,在各个数据不要轻易让浏览器改变,如果允许改变,一定要控制范围!
        size = int(request.GET.get('size'),20)
        size = size if size > 0 and size < 101 else 20
    except:
        size = 20

    try:
        #按照id倒排
        start = (page - 1) * size
        posts = Post.objects.order_by('-id')[start:start+size]
        print(posts.query)
        return JsonResponse({
            'posts':[{
                'post_id':post.id,
                'title':post.title
            }for post in posts]
        })
    except Exception as e:
        print(e)
        return HttpResponseBadRequest

完善分页

改进如下:

def getall(request:HttpRequest):
    try:#页码
        page = int(request.GET.get('page',1))
        page = page if page > 0 else 1
    except:
        page = 1

    try:#页码行数
        #注意,在各个数据不要轻易让浏览器改变,如果允许改变,一定要控制范围!
        size = int(request.GET.get('size'),20)
        size = size if size > 0 and size < 101 else 20
    except:
        size = 20

    try:
        #按照id倒排
        start = (page - 1) * size
        posts = Post.objects.order_by('-id')
        print(posts.query)
        count = posts.count()#记录总数

        posts = posts[start:start+size]#分页按指定size大小显示
        print(posts.query)

        return JsonResponse({
            'posts':[{
                'post_id':post.id,
                'title':post.title
            }for post in posts],
            'pagination':{
                'page':page,
                'size':size,
                'count':count,
                'pages':math.ceil(count/size)#总页数,总数除以分页大小(向上取整)
            }
        })
    except Exception as e:
        print(e)
        return HttpResponseBadRequest

改写校验函数

#在post.views.py中
def validate(d:dict, result:str, type_func, default, validate_func):
    try:
        result = type_func(d.get(result, default))
        result = validate_func(result,default)
    except:
        result = default
    return result

def getall(request:HttpRequest):
    page = validate(request.GET,'page',int,1,lambda x,y: x if x>0 else 1)

    size  = validate(request.GET, 'size', int, 20, lambda x, y: x if x>0 and x<101 else 20)
    try:
        #按照id倒排
        start = (page - 1) * size
        posts = Post.objects.order_by('-id')
        print(posts.query)
        count = posts.count()#记录总数

        posts = posts[start:start+size]#分页按指定size大小显示
        print(posts.query)

        return JsonResponse({
            'posts':[{
                'post_id':post.id,
                'title':post.title
            }for post in posts],
            'pagination':{
                'page':page,
                'size':size,
                'count':count,
                'pages':math.ceil(count/size)#总页数,总数除以分页大小(向上取整)
            }
        })
    except Exception as e:
        print(e)
        return HttpResponseBadRequest
做一枚奔跑的老少年!
原文地址:https://www.cnblogs.com/xiaoshayu520ly/p/11432545.html