Django-Python重量级Web框架

Django是一套完整的MVC开发架构,虽然在微服务盛行的今时今日再谈MVC有些老土,不过对于python这种解决小项目的开发语言来说,MVC仍然是最优的选择。

严格来说,DjangoMTC,因为其表现层用的是模板(Template

 

Django的目录结构

manage.py:Django的命令行工具,可以让我们通过命令形式与Django进行交互。

templates:前台模板文件存放的目录,该目录有时也会放在项目mysite目录的里面,是在settings.py中配置的。

urls.py:路由信息,配置了url地址与代码的映射关系,像Java中的Struts的配置,小型项目一般一个路由配置文件就够了,大型的项目会配置多级路由。

wsgi.py: WSGI 兼容的Web 服务器的入口,以便运行你的项目

 

这里着重要了解下settings.py中的一些配置:

ROOT_URLCONF = 'mysite.urls'
对应路由信息第一级的入口,对于路由多级及详细配置,下面会解释

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'mysite/templates')],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]
这个是配置模板信息的,特别需要注意DIRS这个配置,代表着模板存放的位置,所以前面提到过templates目录的位置是可以自己按照习惯自定义的,当然必须要与这个配置匹配。
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'HOST': '',
        'NAME': 'mysite_dev',
        'USER': '',
        'PASSWORD': '',
    }
}
持久层数据库的配置信息,用于数据库连接


STATICFILES_DIRS = (
    os.path.join(BASE_DIR, '/mysite/static'),
)
STATIC_URL = '/static/'
Js、css、图片等静态文件配置,dirs配置的是静态文件存放的位置,url配置的是请求静态文件的url前缀

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    # 'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
中间件的配置,相当于java的spring中的AOP,前置加强、后置加强、循环加强、异常加强等。
 
 
INSTALLED_APPS = [
    'mysite.apps.job',
    'mysite.apps.product',
    'mysite.apps.plan',
]

一组业务的MVCDjango中被称为一个appINSTALLED_APPS配置的就是装在了哪些app,一个app的目录结构如下:

apps.py:代码很简单,为了完成app的声明:

from django.apps import AppConfig


class TemplateConfig(AppConfig):
    name = 'cloudm.apps.plan'

models.py是持久层ormapping的代码,后面会详细介绍

urls.py是路由的详细配置信息,后面会详细介绍

view.py是属于buusiness层的代码,接收页面的request,处理业务逻辑,调用持久层入库操作结果,返回response给到前台,这个后面也会详细介绍。

 

 

 

路由控制URL

urls.py是整个Django项目的筋络,也是每个app的门户。前面settings中已经介绍了DITS里配置的是路由的总入口,以2层路由为例,看下路由的配置信息。

第一层:
urlpatterns = [
    url(r'^$', views.index),
    url(r'^job/', include("mysite.apps.job.urls")),
    url(r'^product/', include("mysite.apps.product.urls")),
    url(r'^template/', include("mysite.apps.template.urls")),
    url(r'^plan/', include("mysite.apps.plan.urls")),
]

很好理解,根据第一层url的不同引入后续的urls

 

第二层,以plan为例:
urlpatterns = [
    url(r'^$', views.index, name='plan-views-index'),
    url(r'^name/?$', views.create, name='plan-views-name'),
    url(r'^add_plan/?$', views.add_plan, name='plan-views-add'),
    url(r'^add_component/?$', views.add_component, name='plan-views-add-component'),
    url(r'^edit_component/(?P<plan_id>\d+)/?$', views.edit_component, name='plan-views-edit-component'),
    url(r'^edit/(?P<id>\d+)/?$', views.edit, name='plan-views-edit'),
    url(r'^detail/(?P<plan_id>\d+)/?$', views.detail, name='plan-views-detail'),
    url(r'^update_comp/?$', views.update_component, name='plan-views-update-component'),
    url(r'^delete_comp/?$', views.delete_component, name='plan-views-delete-component'),
]

每条配置有3部分,左边部分是url的内容,中间部分对应业务逻辑层views.py中的具体函数,右边部分是在该地址在Django项目中的唯一标识,内部可以直接请求这个标识而不是url发起业务请求。

 

 

 

Model

django中遵循 CodeFrist 的原则,代码既数据,可以通过python manage.py migrate将改动更新到数据库。对于Java开发者理解的ORMapping来说,先建表,然后基于表写模型代码和ORMapping的配置文件。而对于Python开发者来说,模型代码就是表结构本身,写代码的过程是直接建表的过程,而不是映射的过程。

看下planmodels.py
from django.db import models

class Plan(models.Model):
    id = models.BigAutoField(primary_key=True)
    detail = models.TextField(blank=True, null=True)
    create_time = models.DateTimeField(auto_now_add=True)
    update_time = models.DateTimeField(auto_now=True)
    status = models.CharField(max_length=10, blank=True, null=True)
    name = models.CharField(max_length=40, blank=True, null=True)

    class Meta:
        managed = True
        db_table = 'plan'
效果图:

models定义了很多种属性,涵盖了关系型数据库中的所有类型。

看下几种常用的属性:

models.BigAutoField:自增长列,一般用于主键
models.CharField:最常用的,需要定义长度;
models.BooleanField:布尔类型
models.DateField:日期类型,auto_now代表每次更新是否设置为当前时间,auto_now_add代表只有第一次创建时会设置为当前时间。这两个入参很明显一个用在createDate场景,一个用在updateDate场景。
models.Decimal:必须设置精度
models.IntegerField:整型
models.TextField:大文本类型
models.BinaryField:大二进制类型
每个model还定义了一个元数据信息:
db_table:对应在数据库中的表名
managed:是否被python manage.py来管理
index_together:联合索引
unique_together:联合唯一约束

ORMpping中最难掌握的也是唯一的难点,就是Relationship,这里只介绍常用的多对一和多对多。Django中处理多对一的关键字是ForeignKey,同理多对多也是通过桥表来转化成2个多对一。

假设我的任务表叫job,代表每个需要执行的任务。任务不见得每次都能执行成功而且可以重复执行,所以给执行结果保存在job_history中,这样1job就对应多个job_history,每个job_history通过foreignkeyjob关联。

Job_History的核心代码如下:

class JobHistory(models.Model):
    job = models.ForeignKey('Job', models.DO_NOTHING)

其中foreignkey配置的是model的名字,但是在数据库层对应的是modelid。第二个参数代表job删除时关系如何维护,可选项有:

- models.CASCADE,删除关联数据,与之关联也删除 
- models.DO_NOTHING,删除关联数据,引发错误IntegrityError 
- models.PROTECT,删除关联数据,引发错误ProtectedError 
- models.SET_NULL,删除关联数据,与之关联的值设置为null(前提FK字段需要设置为可空) 
- models.SET_DEFAULT,删除关联数据,与之关联的值设置为默认值(前提FK字段需要设置默认值) - models.SET,删除关联数据,
多对多可以拆解成2个多对一,假设操作人userjob是多对多的关系,一个job可以被多人经手操作,同理一个人可能参与多个job,我们可以创建一个user2jobmodel
class User2Job(models.Model):
    job = models.ForeignKey('Job', models.DO_NOTHING)
user= models.ForeignKey('User', models.DO_NOTHING)
class Meta:
unique_together = ("job","user")

Django对多对多还提供了ManyToManyField这种方式,我自己倾向于拆解。

 

增删改查:

Object.save()其实是saveOrUpdate()object.delete()是删除,所以模型的增删改查就剩下查询比较复杂了。

常用的查询方式有:

Get:直接通过条件获取确定的model对象,例如:

resource = Resource.objects.get(id=resource_id)

Filter:相当于where条件过滤

resource = Resource.objects.filter(job_id=job_id,type_id=1).first()

查询后跟.count()是取总数,不带任何条件直接.all()是取全部,.order_by是按属性排序

批量删除:

Application.objects.filter(id=data['app_id']).delete()

范围查询:

models.Tb1.objects.filter(id__lt=10,id__gt=1)

id小于1切大于10

models.Tb1.objects.exclude(id__in=[11, 22,33])

id not in [11,22,33]

 

关于Django的模型先介绍到这里,注意:每个app的模型定义的python文件名是models而不是model,也就是说并不是每张表结构创建一个app,我们要把多个相关的模型定义在一个模型文件中,views.pyurls.py同理,那么问题来了,哪些表属于同一个app?这就涉及到软件开发设计领域的另一个课题DDD(领域驱动设计),建议大家学习掌握。

 

 

View层:

View要做的事情主要有2部分,第一、处理页面的requestresponse,第二、组织业务逻辑并调用持久层(models)。对持久层的操作就是增删改查,对于业务逻辑的编程那就是跟自己业务相关的了,没什么好介绍的,那么View层唯一需要掌握的就剩下RequestResponse了。

View层函数入参是request,代表客户端传来的请求,我们需要根据http的具体请求方法(getpostput等)来选择如何获取request中的内容。

Response一般分直接返回Json和返回页面2种。

返回Json
return JsonResponse(ret)
返回页面:
return render(request, "job/index.html", {'jobs': jobs})

obs”job/index.html”这个前台页面需要加载的变量内容。
 
 
Template层:
这一层是概念理解上最简单,但是后期工作量最大的一层。核心思想就是block,利用模板的继承,前面flask有类似的使用,这里也不再详细描述了。

 

 

最后看下Django的常用命令:

python manage.py migrate

前面已经介绍过了,是models与数据库的同步命令。

 

python manage.py runserver ip:port

是项目的启动命令,ip:port是接收服务的地址,一般配置为0:8000

 

python manage.py createsuperuser

创建超级管理员






猜你喜欢

转载自blog.csdn.net/yejingtao703/article/details/80602657