day9

反向工程

# 正向工程 - 模型变表 - 项目规模较小没有专业的DBA
# python manage.py makemigration<应用名>
# 反向工程 - 表变模型 -项目规模较大公司由专业DBA
# python manage.py inspectdb > <appname>/models.py
# 由数据库迁移数据
from django.db import models

class District(models.Model):
    distid = models.IntegerField(primary_key=True)
    parent = models.ForeignKey(to='self',on_delete=models.PROTECT,db_column='pid',blank=True, null=True)
    name = models.CharField(max_length=255)
    ishot = models.BooleanField(default=False)
    intro = models.CharField(max_length=255,default='')

    class Meta:
        managed = False
        db_table = 'tb_district'

过滤数据

django-filter库包含一个DjangoFilterBackend

如果需要过滤数据(对数据接口设置筛选条件、排序条件等),可以使用django-filter三方库来实现。

pip install django-filter
INSTALLED_APPS = [
    
    'django_filters',

]
REST_FRAMEWORK = {
    # 默认的后端过滤器
    'DEFAULT_FILTER_BACKENDS': (
        'django_filters.rest_framework.DjangoFilterBackend',
        'rest_framework.filters.OrderingFilter',
    ),
    
}
过滤器api/utils

    """自定义记录数据过滤器"""
class RecordFilterSet(django_filters.FilterSet):
    #过滤器
    # carno调用自定义方法
    carno = django_filters.CharFilter(method='filter_by_carno')
    # gte最小值 lte最大值
    min_date = django_filters.DateTimeFilter(field_name='makedate',lookup_expr='gte')
    max_date = django_filters.DateTimeFilter(field_name='makedate',lookup_expr='lte')

    @staticmethod
    def filter_by_carno(queryset,name,value):
    # 置换空格
        value = normalize(value)
        # 设置过滤条件car的carno、owner属性(模糊)/value为?carno=川A12345&owner=王 中的值
        return queryset.filter(Q(car__carno=value)|
                               Q(car__owner__contains=value))

    class Meta:
        model = Record
        # 根据这些项进行过滤
        fields = ('carno','min_date','max_date')
  视图函数
  # 设置缓存过期时间为1S,缓存调用默认缓存,在settings文件中修改,修改数据和查找的缓存
@method_decorator(decorator=cache_page(timeout=1, cache='default'),name='retrieve')
@method_decorator(decorator=cache_page(timeout=1, cache='default'),name='list')
class RecordViewSet(ModelViewSet):
    """违章记录视图集合"""
    # 内连接查询
    queryset = Record.objects.all().select_related('car')
    # 限流类
    throttle_classes = ()
    # 序列化器
    serializer_class = RecordSerializer
    # 后端过滤器
    filter_backends = (DjangoFilterBackend,OrderingFilter)
    # 排序方式
    ordering = ('-makedate')
    # 排序类调用自定义排序类
    filterset_class = RecordFilterSet

drf的第三种方法

fbv在视图里使用函数处理请求。

cbv在视图里使用类处理请求。

定义序列化器api/serializers

class DistrictSerializer(serializers.ModelSerializer):


    class Meta:
        model = District
        exclude = ('parent','ishot')


class DistrictDetailSerializer(serializers.ModelSerializer):
# 在这个模型中,没有这个字段使用SerializerMethodField,当用户获取这个数据,调用函数返回给用户
    cities =  serializers.SerializerMethodField()
    # 定义静态方法,回调函数
    # parent=district进行筛选
    # 返回data数据
    @staticmethod
    # 当传入district的时候回调方法get_cities
    def get_cities(district):
    # 取到parent=district的对象
        cities = District.objects.filter(parent=district)
        return DistrictSerializer(cities,many=True).data

    class Meta:
        model = District
        fields = ('distid','name','intro','cities')

使用装饰器,编写函数方法的视图函数

@api_view(['GET'])
@cache_page(timeout=None, cache='api')
def provinces(request):
# queryset获取查询对象
    queryset = District.objects.filter(parent__isnull=True)
    # 进行序列化 调用Serializer
    serializer = DistrictSerializer(queryset, many=True)
    # 返回数据,通过data属性可以获取序列化后的数据
    return Response(serializer.data)


@api_view(['GET'])
def get_districts(request,distid):
# distid = url传入的<int:distid>进行筛选
    district = District.objects.filter(distid=distid).first()
    serializer = DistrictDetailSerializer(district)
    return Response(serializer.data)
urlpatterns = [
    path('districts/', get_provinces),
    path('districts/<int:distid>/', get_districts),
  ]   # 映射url districts/130000/

使用了Django自带的视图装饰器(@cache_page)来实现对API接口返回数据的缓存。可以使用多种装饰器 但需要在api_view下使用

函数方法中的分页器使用

获取url参数,127.0.0.1:8000/?page=<value>

# 非法数值则返回1 数值为空也返回1 如 127.0.0.1:8000/?page=asdsa
page = int(request.GET.get('page','1'))
size = int(request.GET.get('size','5'))
print(size,page)
queryset = District.objects.filter(parent__isnull=True)
# 每5份内容分页一次
paginator = Paginator(queryset,size)
serializer = DistrictSerializer(paginator.page(page).object_list,many=True)
return Response(serializer.data)

使用APIView及其子类/使用ViewSet及其子类

让浏览器能够发起DELETE/PUT/PATCH

 <script>
        const app = new Vue({
            el: '#app',
            data: {
                records: [],
                carno: '',
                minDate:'',
                maxDate:'',
                currentPage: 1,
                totalPage: 0,
                loaded: false
            },
            methods: {
                getData() {
                    let carno = this.carno.trim()
                    fetch(`/api/records/?carno=${carno}&min_date=${this.minDate}&max_date=${this.maxDate}&page=${this.currentPage}`)
                        .then(resp => resp.json())
                        .then(json => {
                            this.records = json.results
                            this.totalPage = parseInt((json.count - 1) / 5) + 1
                            console.log(json.results)
                        })
                },
                change() {
                    this.loaded = false
                },
                search() {
                    this.currentPage = 1
                    this.totalPage = 0
                    this.getData()
                    this.loaded = true
                },
                // fetch的PATCH方法将数据上传
                handleItem(record) {
                // 数据接口
                    fetch(`/api/records/${record.id}/`, {
                        method: 'PATCH',
                          // 上传数据
                        body: JSON.stringify({dealt: true}),
                        headers: {
                        // 数据类型 json
                            'content-type': 'application/json'
                        }
                    })
                    // 请求json
                        .then(resp => resp.json())
                        // 页面刷新
                        .then(json => record.dealt = json.dealt)
                },
                deleteItem(record) {
                    if (confirm('确定要删除吗?')) {
                        fetch(`/api/records/${record.id}/`, {
                        // 删除方法
                            method: 'DELETE'
                        })
                            .then(resp => {
                            // 204提示删除成功
                                if (resp.status == 204) {
                                // 根据下标删除记录
                                    let index = this.records.indexOf(record)
                                    this.records.splice(index, 1)
                                   }
                            })
                    }
                }
            }
        })
    </script>
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,884评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,755评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,369评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,799评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,910评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,096评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,159评论 3 411
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,917评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,360评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,673评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,814评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,509评论 4 334
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,156评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,882评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,123评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,641评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,728评论 2 351

推荐阅读更多精彩内容

  • 第十八章 Django入门 一、建立项目 项目规范:项目规范详细说明了项目的目标,阐述了项目的功能,并讨论了项目的...
    DKJImmy阅读 2,164评论 1 49
  • 一、日志使用指南 前言 在django中对日志记录提供了很好的支持,日志文件在开发环境中以及在线上环境或者在测试环...
    旧时初_2e8d阅读 609评论 0 1
  • 函数 1、什么是函数 是实现某一特定功能的代码块的封装 2、函数的分类 系统函数(内置函数) - 系统已经实现了的...
    Error_2d57阅读 113评论 0 0
  • 一、变量的作用域 1、变量的作用域 变量在程序中能够使用的范围 2、全局变量 a.声明在函数或者类的外部的变量都是...
    w的狗子啊阅读 398评论 0 0
  • day9-0812 上次在用form做文件上传的时候,自己方便测试使用koa搭建了一个临时后台「其实很早之前就已经...
    亨利何阅读 217评论 0 0