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

相关文章

来自专栏程序员的SOD蜜

Oracle 免费的数据库--Database 快捷版 11g 安装使用与"SOD框架"对Oracle的CodeFirst支持

一、Oracle XE 数据库与连接工具安装使用 Oracle数据库历来以价格昂贵出名,当然贵有贵的道理,成为一个Oracle DBA也是令人羡慕的事情,如果程...

3327
来自专栏散尽浮华

mysqldump数据导出问题和客户端授权后连接失败问题

1,使用mysqldump时报错(1064),这个是因为mysqldump版本太低与当前数据库版本不一致导致的。 mysqldump: Couldn't exe...

2069
来自专栏张戈的专栏

MySQL命令行工具:percona-toolkit安装使用初探

导读:percona-toolkit 源自 Maatkit 和 Aspersa 工具,这两个工具是管理 mysql 的最有名的工具,现在 Maatkit 工具已...

3607
来自专栏张善友的专栏

在 CentOS 上使用 Jexus 托管运行 ZKEACMS

ZKEACMS Core 是基于 .net core 开发的,可以在 windows, linux, mac 上跨平台运行,接下来我们来看看如何在 CentOS...

6410
来自专栏自由而无用的灵魂的碎碎念

将MySQL数据迁移到Oracle

因为项目的原因,今晚将mysql数据库的内容尝试迁移到oracle,虽然结果失败,不过学到了不少,下次就不一定了,哈哈

841
来自专栏bboysoul

检查你的系统中是不是还有Spectre & Meltdown漏洞

这两个漏洞详细的我就不多说了,自己去百度,反正这两个东西忙坏了云服务厂商就对了,目前只要你的系统更新过,不管windows,ios,安卓,mac还是linux,...

472
来自专栏帘卷西风的专栏

关于cocos2dx3.0 UITextField不能使用退格键删除字符的解决方案

    近日开始将项目移植到cocos2dx 3.0版本,出现了一些问题,UI方面目前就发现UITextField控件不能响应退格键或者删除键,在Window...

582
来自专栏圣杰的专栏

ABP入门系列(21)——切换MySQL数据库

源码路径:Github-LearningMpaAbp 1. 引言 Abp支持MySql已经不是什么新鲜事了,但按照官方文档:Entity Framework...

2269
来自专栏张善友的专栏

在CentOS上使用Jexus托管运行 ZKEACMS

ZKEACMS Core 是基于 .net core 开发的,可以在 windows, linux, mac 上跨平台运行,接下来我们来看看如何在 CentOS...

1875
来自专栏乐沙弥的世界

安装MySQL样本数据库Sakila

    通常情况下对于一个全新的MySQL服务器,没有任何数据供我们测试和使用。对此,MySQL为我们提供了一些样本数据库,我们可以基于这些数据库作基本的操作以...

673

扫码关注云+社区