首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Django数据处理的一些实践

Django数据处理的一些实践

原创
作者头像
唐郑望
修改2017-10-09 09:54:35
1.2K0
修改2017-10-09 09:54:35
举报
文章被收录于专栏:唐郑望的专栏唐郑望的专栏

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

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一时爽,重构火葬场

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

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

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

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

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • MVC模式
  • 数据交互
  • 总结与感悟
    • 人生苦短,我用Python
      • Python一时爽,重构火葬场
        • 如有错误欢迎各位大大不吝指正,感谢!
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档