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 条评论
登录 后参与评论

相关文章

来自专栏数据和云

从商用到开源:15个维度,全面剖析DB2与MySQL数据库的差异

编辑手记 MySQL是目前最流行的开源数据库,由于其部署方便,运维简单,被广泛用于互联网的各个领域。随着整体IT架构的变更,传统的金融,电信业务,也逐渐走上从商...

6567
来自专栏逸鹏说道

程序猿是如何解决SQLServer占CPU100%的

文章目录 遇到的问题 使用SQLServer Profiler监控数据库 SQL1:查找最新的30条告警事件 SQL2:获取当前的总报警记录数 有哪些SQL语句...

3788
来自专栏coding

2018年swoole实战5-异步mysql模拟数据异步mysql连接时长

1122
来自专栏乐沙弥的世界

Oracle 闪回特性(Flashback Version、Flashback Transaction)

--==========================================================

792
来自专栏乐沙弥的世界

MySQL 状态变量(Server Status Variables)

    MySQL状态变量是当前服务器自启动后累计的一些系统状态信息,主要用于评估当前系统资源的使用情况以进一步分析系统性能而做出相应的调整决策。这些状态变量我...

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

关于date格式的两个案例(r4笔记第96天)

在工作中总是会碰到各种和date相关的问题,一般这种问题都是让人很纠结的。 比如前几天一个朋友和我分享了他关于时间问题的两个案例。 第一个是他在做impdp导入...

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

迁移式升级的测试(三)(r10笔记第36天)

还是继续昨天的任务。 前面的内容可以参见:迁移式升级的一点思考 (r10笔记第27天)、迁移式升级的新方案测试 (r10笔记第30天)、迁移式升级的测试(二)(...

3575
来自专栏idba

MySQL 5.7 新特性之三

本系列文章基于5.7.20 版本讲述MySQL的新特性,从安装,文件结构,SQL,优化,复制等几个方面展开介绍5.7 的新特性和功能,同时也建议大家跟踪官方bl...

982
来自专栏Hongten

SQL SERVER事务处理

事务三种运行模式: 自动提交事务 每条单独的语句都是一个事务。 显式事务 每个事务均以 BEGIN TRANSACTION 语句显式开始, 以 COMMIT 或...

3602
来自专栏沃趣科技

MVCC原理探究及MySQL源码实现分析

目录预览 数据库多版本读场景 MVCC实现原理 1、通过DB_ROLL_PT 回溯查找数据历史版本 2、通过read view判断行...

6118

扫码关注云+社区

领取腾讯云代金券