Django数据处理的一些实践

导语:一名校招新人入职一个月的一些总结与感悟

MVC模式

提到Django肯定避不开MVC模式,即模型(Model)-视图(View)-控制器(Controller),通过将业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个模块里面,在通过个性化界面与用户交互的同时,不需要重新编写业务逻辑。具体到django里面,我个人的观点是http请求通过对应的urls.py映射到指定的views.py内,views.pymodels.py定义的数据模型映射到数据库进行交互并完成业务逻辑的处理,最后将处理结果在views.py里以httpresponse的形式进行返回。

举个简单的例子:

在终端里面发出如下curl请求:

curl -XPOST 127.0.0.1/test/getTaskDetail -d '{"taskId": 521}'

在指定的目录下的test文件夹里面,urls.py里对应有这样一行配置进行路由:

url('^getTaskDetail$', 'get_task_detail', name="get_task_detail"),

(需要提醒的是,如果该行代码不在最后,结尾的逗号","一定别忘了)

这样getTaskDetail这个request就会被映射views.py里面的get_task_detail这个接口:

@login_require
def get_task_detail(request):
    '''
    Processing Logic
    '''
    return HttpJsonResponse()

数据交互

上文没有涉及到与数据库的交互,这里单独做整理,这也是最近项目中涉及最多的一块内容。

比如现在要在数据库中新建一张task表

CREATE TABLE `task`(
    `id` int(11) NOT NULL auto_increment,
    `name` varchar(255) NOT NULL DEFAULT "",
    `created` datetime NOT NULL DEFAULT "2017-08-28 20:00:00",
    `timeout` int(11) NOT NULL DEFAULT 0,
    `uin` varchar(20) NOT NULL DEFAULT "",
     PRIMARY KEY (`id`)
    ) ENGINE=InnoDB  DEFAULT CHARSET=utf8

还有一张运行时的taskrun表

CREATE TABLE `taskrun`(
    `id` int(11) NOT NULL auto_increment,
    'task_id' int(11) NOT NULL DEFAULT 0,
    `status` smallint(6) NOT NULL DEFAULT 0,
    `build_result` longtext NOT NULL DEFAULT "",
    `uin` varchar(20) NOT NULL DEFAULT "",
     PRIMARY KEY (`id`)
    ) ENGINE=InnoDB  DEFAULT CHARSET=utf8

对应到models.py里面定义的数据模型,可以看到如下定义

class Task(models.Model):
    name     = models.CharField(max_length=255, help_text=u"任务名")
    created  = models.DateTimeField(auto_now_add=True,help_text=u"创建时间")
    timeout  = models.IntegerField(help_text=u"超时时间")
    uin      = models.CharField(max_length=20, db_index=True, help_text="uin") 
    class Meta:
        db_table = 'task' 
class CiTaskRun(models.Model):
    task         = models.ForeignKey(Task)
    status       = models.SmallIntegerField(help_text=u"任务状态")
    build_result = models.TextField(help_text=u"构建结果")
    uin          = models.CharField(max_length=20, db_index=True, help_text="uin") 
    class Meta:
        db_table='taskrun'

有三点需要注意

  • models.py里没有设置primary key的话,Django默认为每张表新建一个名叫id的列,为主键列。如果你的表里面有一列叫id,且不设置它为主键的话,是会产生冲突的。
  • models.py里默认会为每张表的外键列设置一个格式为 "表名(全小写)_id" 的列,例如taskrun表中的task_id那一列。
  • models.py默认会为每张表命名为"数据库_表名",可以像上面代码里的那样通过设置db_table的形式来自定义表名。

在Django中需要在settings.py中配置的数据库,比如

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'my_test',
        'USER': 'root',
        'PASSWORD': '123',
        'HOST': '127.0.0.1',
        'PORT': '3306',
    }
}

如果在项目中需要用到多个数据库,可以这样进行操作,在上述代码下面进行添加

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'my_test',
        'USER': 'root',
        'PASSWORD': '123',
        'HOST': '127.0.0.1',
        'PORT': '3306',
    },
    'test2': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'my_test_2',
        'USER': 'root',
        'PASSWORD': '321',
        'HOST': '127.0.0.1',
        'PORT': '3306',
    }
}

( 注意跟"default"对应的"test2"标签)

然后需要在settings.py中进行数据库路由的配置,比如

DATABASE_ROUTERS = ['test.router.testRouter']

这样在test目录下的router.py文件中需要定义testRouter,配置上文提到的test2标签

class testRouter(object):
    """Allows each model to set its own destiny"""
    def db_for_read(self, model, **hints):
        if model._meta.app_label == 'test2':
            return 'test2'       
        return None

    def db_for_write(self, model, **hints):
        if model._meta.app_label == 'test2':
            return 'test2'
        return None

最后在对应的表里面通过设置 default app_label = 'test2'就访问非默认的数据库

class Task(models.Model):
    name     = models.CharField(max_length=255, help_text=u"任务名")
    created  = models.DateTimeField(auto_now_add=True,help_text=u"创建时间")
    timeout  = models.IntegerField(help_text=u"超时时间")
    uin      = models.CharField(max_length=20, db_index=True, help_text="uin") 
    class Meta:
        app_label='test2'
        db_table = 'task' 

这样就可以实现对多个不同的数据库中的多张表进行同时访问了。

Django里面与数据库交互一些API,比如

task_list = Task.objects.filter(uin= uin).order_by('created')

对应的sql语句为

select * from task where uin = uin order by created asc;

具体的就不多赘述了,可以参考下API手册。

总结与感悟

人生苦短,我用Python

提到python肯定离不开这句话,做为一名校招新人,第一次接触Django框架,在这段时间的封闭开发中也体验到了python所带来的便捷之处,上手起来确实很快,在短短的一个月时间内对于Django的印象也是很轻巧,整体MVC的架构包括对ORM的支持让用户使用起来也觉得比较方便。

Python一时爽,重构火葬场

这是同事说的一句话。因为整个封闭过程中需要对另外一个项目组的一个工程进行一部分重构,这期间涉及到的版本控制,文件依赖等各种问题确实也浪费了一部分时间去处理,包括最后的测试方面也暴露除了动态脚本语言的一些局限性,既然选择了就得接受,这是我的看法。

如有错误欢迎各位大大不吝指正,感谢!

原创声明,本文系作者授权云+社区-专栏发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

唐郑望的专栏

1 篇文章1 人订阅

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏杨建荣的学习笔记

闪回原理测试(二)(r11笔记第23天)

对于闪回部分,Oracle本身提供了非常多相关的特性,我个人对于闪回数据库这个特性最为喜爱,尤其是应用再Data Guard环境中,真是一大杀器。 ...

34510
来自专栏数据和云

Oracle数据库的初始化与跟踪学习方法

编辑说明:《Oracle性能优化与诊断案例精选》出版以来,收到很多读者的来信和评论,我们会通过连载的形式将书中内容公布出来,希望书中内容能够帮助到更多的读者朋友...

3399
来自专栏杨建荣的学习笔记

根据时间字段导入数据的问题总结 (r6笔记第6天)

在之前的博文中介绍过如何通过exchange partition,split partition达到快速的数据切换,对于上百G的大表来说,速度都在秒级完成 对...

2596
来自专栏杨建荣的学习笔记

外部表简单总结(r3笔记第51天)

对于外部表的使用而言,可能是既陌生又熟悉的感觉,说陌生可能自己真正的使用机会要少一些,而熟悉可能是大家比较常用的通过外部表来查看数据库日志,其实外部表还有更丰富...

26711
来自专栏杨建荣的学习笔记

MySQL主从不一致的修复过程(r10笔记第96天)

昨天发现一个5.7的MySQL从库在应用日志的时候报出了错误。从库启用过了并行复制。Last Error的内容为: Last_Error: Coordinato...

3469
来自专栏乐沙弥的世界

使用pt-table-checksum校验MySQL主从复制

pt-table-checksum是一个基于MySQL数据库主从架构在线数据一致性校验工具。其工作原理在主库上运行, 通过对同步的表在主从段执行checksum...

642
来自专栏数据和云

时过境迁:Oracle跨平台迁移之XTTS方案与实践

作者简介 ? 谢金融 云和恩墨东区交付部 Oracle 工程师,多年来从事 Oracle 第三方服务,曾服务过金融、制造业、物流、政府等许多行业的客户,精通数据...

40010
来自专栏乐沙弥的世界

Oracle 热备份

Oracle 热备份是指数据库处于open状态下,对数据库的数据文件、控制文件、参数文件、密码文件等进行一系列备份操作。

441
来自专栏乐沙弥的世界

基于同一主机配置 Oracle 11g Data Guard

       Oracle Data Guard 为企业数据库提供了最有效和最全面的数据可用性、数据保护和灾难恢复解决方案。它集成管理、监视和自动化软件基础架构...

621
来自专栏散尽浮华

Oracle数据库冷备份与热备份操作梳理

Oracle数据库的备份方式有冷备份和热备份两种,针对这两种备份的实施过程记录如下: 一、Oracle冷备份 概念 数据库在关闭状态下完成所有物理系统文件拷贝的...

2348

扫码关注云+社区