django model filter_Django的使用及原理介绍[1]初识Django

1

概述

在python实现的web框架中,最为流行的要数据django和flask的,django是一个重型框架,主要的目标是使开发复杂的、数据库驱动的网站变得简单。这类框架包含了创建应用的几乎全部功能,如安全认证、URL routing、处理请求的视图系统、模板引擎、ORM及数据库schema映射等。此外,django具有很好的扩展性及性能。与Django类似的重型框架还包括Pyramid、TurboGears及Web2py等。Django官网对自己的解释为:           7ab98b752e2adf033093970f75db2722.png

Flask是最流行的Python轻量级Web框架,目的是要建立一个非常稳定和可靠的Web应用的基础系统,Flask本身包含的功能并不全,但可以加上各种插件,扩展和其他模块构建功能强大的网站和应用,达到与Django框架一样能够支持复杂系统的需求。Flask基于Werkzeug WSGI toolkit以及 Jinja2 模板。本系列文章会围绕Django的使用和内部原理展开介绍,暂不展开介绍Flask,后续以单独的系列文章对Flask进行介绍。代码git repo:https://github.com/836304831/mp_weixin

2Django应用开发准备

Django应用开发准备主要包括Django软件包的安装及开发环境生成。本文的实验环境为linux环境,在安装django之前,系统需要安装python的开发环境,可参考教程。安装好python开发环境后,使用pip 命令安装。

pip install django==1.8  # 也可以直接安装最新版本

pip install rest_framework

pip install django-rest-swagger

安装完成后,打开终端,输入django-admin, 若提示帮助,则说明安装成功,如下:fd81facb05ffc369f2fe63673fa7328c.png

依赖安装好之后即可创建Django应用,先创建工程django-demo,然后在django-demo工程下执行:

django-admin startproject apps .

运行上述命令后,在django-demo目录下会生成一些文件,如下图:           faead234e04d4e24776448b5890bd855.png

  • manage.py: 主要代码如下,是用来和项目交互的命令行的工具。是对django-admin.py工具的一个简单包装, 后续的开发过程中,可能会管理多个应用,所以“DJANGO_SETTINGS_MODULE”的环境变量可能需要修改一下(后续会介绍相关内容)。

if __name__ == '__main__':   os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'apps.settings')   try:       from django.core.management import execute_from_command_line   except ImportError as exc:       raise ImportError(           "Couldn't import Django. Are you sure it's installed and "           "available on your PYTHONPATH environment variable? Did you "           "forget to activate a virtual environment?"       ) from exc   execute_from_command_line(sys.argv)
  • apps/urls.py:主要代码如下,是url入口,默认的admin是django后台的访问地址,对应的功能也已经实现。业务相关的地址需要开发者自行添加。一般来说,一个url关联一个处理视图(view),在视图中处理相关的业务逻辑。

from django.contrib import adminfrom django.urls import pathurlpatterns = [   path('admin/', admin.site.urls),]
  • apps/settings.py:Django的配置文件,在实际的业务开发过程中需要修改文件,主要修改的点包括:应用列表添加(开发者创建的应用),根url的配置,数据库的配置,django访问权限级别控制。主要代码如下:

INSTALLED_APPS = [   'django.contrib.admin',   'django.contrib.staticfiles',   'apps'  # 添加创建的“apps”应用]ROOT_URLCONF = 'apps.urls'  # 管理多个应用时可能需要修改# 权限的控制,请求数据库分页的大小等REST_FRAMEWORK = {   'DEFAULT_AUTHENTICATION_CLASSES': (       'rest_framework.authentication.SessionAuthentication',   ),   'DEFAULT_PERMISSION_CLASSES': (       'rest_framework.permissions.IsAuthenticated',       # 'rest_framework.permissions.DjangoModelPermissions',   ),   'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',   'PAGE_SIZE': 1000}WSGI_APPLICATION = 'apps.wsgi.application'  # wsgi启动应用配置# 数据库配置,为每个应用单独配置,每个应用可以是不同类型数据库DATABASES = {   'default': {       'ENGINE': 'django.db.backends.sqlite3',       'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),   }}
  • apps/wsgi.py:配置你的项目,让它作为一个WSGI程序来运行。

生成上述文件之后,终端运行:

python  manage.py runserver

按提示代开127.0.0.1:8000, 可以看到如下页面,则表示django的应用开发环境准备就绪。  6aee8bfb16a8a3a5ef2c4dc83490a304.png

3开发自己的Django应用

Django的主要目标是使得开发复杂的、数据库驱动的网站变得简单。所以其中一个很重要的功能是对数据库表进行管理,包括表的model定义,视图定义,model操作接口实现等。下面以书籍的管理为基础,在第二部分生成的apps环境的基础上介绍如何使用Django开发自己的应用。

一般来说,一个Django会包含多个应用,为了更好的管理,我们在apps目录下通过创建书籍管理应用bm模块(通过"django-admin startproject bm ."创建会重复生成manage.py文件等文件,需要手动调整,建议手动创建),跟书籍管理的相关py文件均在bm模块中实现。bm模块中一般包含models.py, serializers.py, views.py, url.py, admin.py, 一般还会在bm目录下加一个tests目录,用于接口的单元测试。添加bm的模块之后的目录如下:

4216eb331c65cbd40bf78b5dc128b32c.png

apps目录下的db目录是手动创建的,用于存放应用创建的数据库文件。 下面一一介绍bm模块下的各个文件的实现。

3.1 models.py文件介绍

Model.py文件是定义数据表model的文件,需要引用django.db.models,本项目定义了BaseTimeStamp、BaseStatus、ModelFiltered 、Title、Author和Book几个类,其中BaseTimeStamp、BaseStatus分别定义创建时间,更新时间及记录是否可见的基础字段,其他表均会继承这两个类。ModelFiltere类是过滤字段的类,具体使用见该文件。Title、Author和Book这三个类对应我们创建的三个表(类型定义了表字段),下文提到的表的概念,指的就是这个表。models.py内容如下:

from django.db import modelsclass BaseTimeStamp(models.Model):   created_at = models.DateTimeField(auto_now_add=True)   updated_at = models.DateTimeField(auto_now=True)   class Meta:       abstract = Trueclass BaseStatus(models.Model):   STATUS_ENABLED = 0   STAUS_DISABLED = 1   STATUS_CHOICE = (       (STATUS_ENABLED, 'enabled'),       (STAUS_DISABLED, 'disabled')   )   status = models.SmallIntegerField(choices=STATUS_CHOICE, default=STATUS_ENABLED)   class Meta:       abstract = Trueclass ModelFiltered(object):   @staticmethod   def get_model_field_names(cls, excludes=[], includes=[]):       fields = list(map(lambda model_field: model_field.name , cls._meta.fields))       filtered = list(filter(lambda field_name: field_name not in excludes, fields))       filtered.extend(includes)       return filteredclass Title(BaseTimeStamp, BaseStatus):   name = models.CharField(max_length=128, verbose_name='title')   @staticmethod   def get_serializer_fields():       return ModelFiltered.get_model_field_names(Title)   @ staticmethod   def get_admin_display_fields():       return ModelFiltered.get_model_field_names(Title)   class Meta:       ordering = ('created_at', )class Author(BaseTimeStamp, BaseStatus):    passclass Book(BaseTimeStamp, BaseStatus):    pass

其中Title和Author类中定义的是django支持的类型,Book类中定义了django支持的类型外,还将Title和Author两个表作为外键引入。BaseStatus的作用是用于用于逻辑删除,BaseTimeStamp的作用是表示创建和更新的时间,两者在多个表中均会用到,所以抽象为通用类。

3.2 serializers.py文件介绍

该文件是对数据表字段进行序列化得文件,一个表对应的序列化类,表的定义在models.py中,servializers.py的内容如下:

from rest_framework import serializersfrom . models import Title, Author, Bookclass TitleSerializer(serializers.ModelSerializer):   class Meta:       model = Title       fields = Title.get_serializer_fields()class AuthorSerializer(serializers.ModelSerializer):   class Meta:       model = Author       fields = Author.get_serialier_fields()class BookSerializer(serializers.ModelSerializer):   class Meta:       model = Book       fields = Book.get_serialier_fields()   def to_representation(self, instance):       self.fields['title'] = TitleSerializer(read_only=True)       self.fields['author'] = AuthorSerializer(read_only=True)       return super(BookSerializer, self).to_representation(instance)

注意,book表的序列化中重写了to_representation方法,主要是因为该表中包含了Title和Author两个外键,改写后读取数据时可以完整的读取外键的各个字段。

tips:本文的例子中,采取外键关联的方式创建表,但是在实际的应用中,处于管理方便和性能考虑,表中不关联外键。

3.3 views.py文件介绍

该文件是表的视图文件,对表进行操作,文件中的每一个类都需要继承rest_framework.generics模块中的父类,这些父类定义了支持的操作,整体包含了get, post, put, patch, delete方法(与http支持的方法相似),不同的支持的方法个数和种类也不一致,具体实现是可根据自身需要选择继承不同的方法。views.py文件的内容如下:

from . models import Title, Author, Book, BaseStatusfrom . serializers import TitleSerializer, AuthorSerializer, BookSerializerfrom rest_framework import genericsfrom django.shortcuts import get_object_or_404from django.db.models import Qclass TitleList(generics.ListAPIView):   queryset = Title.objects.all().filter(~Q(status=BaseStatus.STAUS_DISABLED))   serializer_class = TitleSerializerclass TitleUpdate(generics.ListCreateAPIView):   queryset = Title.objects.all().filter(~Q(status=BaseStatus.STAUS_DISABLED))   serializer_class = TitleSerializerclass TitleDetail(generics.RetrieveUpdateDestroyAPIView):   queryset = Title.objects.all().filter(~Q(status=BaseStatus.STAUS_DISABLED))   serializer_class = TitleSerializer# Author, Book implement ingnored

3.4 urls.py文件介绍

urls.py是定义操作数据表的url,每个url对应views.py中的一个类,表示支持的操作。urls.py的内容如下:

from django.urls import path, re_pathfrom rest_framework.urlpatterns import format_suffix_patternsfrom django.views.decorators.csrf import csrf_exemptfrom . import viewsurlpatterns = [   path('titles/', views.TitleList.as_view()),   path('title/', views.TitleUpdate.as_view()),   path('title/', views.TitleDetail.as_view()),      path('authors/', views.AuthorList.as_view()),   path('author/', views.AuthorUpdate.as_view()),   path('author/', views.AuthorDetail.as_view()),      path('books/', views.BookList.as_view()),   path('book/', views.BookUpdate.as_view()),   path('book/', views.BookDetail.as_view()),   path('book/by_press/', views.BookByPress.as_view()),]
3.5 admin.py文件介绍

 Django自带一个管理数据库的web服务,所以需要将我们需要管理的表添加到admin.py中,这样就可以通过Django自带的web服务对表进行操作了。Admin.py的内容如下:

from django.contrib import adminfrom . models import Title, Author, Book@admin.register(Title)class TitleAdmin(admin.ModelAdmin):   list_display = Title.get_admin_display_fields()@admin.register(Book)class BookAdmin(admin.ModelAdmin):   list_display = [*Book.get_admin_display_fields(), 'get_title', 'get_author']   def get_title(self, obj):       return obj.title.name if obj.title is not None else ''   get_title.admin_order_field = 'title'   get_title.short_description = 'title'   def get_author(self, obj):       return obj.author.name if obj.author is not None else ''   get_author.admin_order_field = 'author'   get_author.short_description = 'author'# author implement ignored

需要注意的是BookAdmin类里边包含了外键的操作,其方法与不包含外键的操作不一样。

4应用配置

开发完bm应用之后,需要将bm应用添加到django中,应用的添加在apps下的settings.py中,该文件是通过django-admin生成Django项目是生成的,添加bm服务,需要修改内容如下:添加INSTALLED_APPS,在原来的基础上添加一些其他的应用,如下图:

0e7cbd73ac7a140850432b010ded57f0.png            

添加REST_FRAMEWORK的基本组件,支持权限的控制和全局数据库查询分页配置,如下:           161132942a5fa2d6da3d2497a7e44aa5.png

数据库配置,可以配置不同的数据库,Django支持常见的mysql,posgres等数据库,可根据需要配置,本文实验使用sqlite3数据库。      9d07c9c4e65dee9667201c6806142f33.png

配置一个默认数据库,用于存储Django自身相关的数据(后续会介绍包含的数据)。

在bm模块中实现了urls.py,还需要将其添加到apps/urls.py中,才可以正常访问到,代码如下:

from django.contrib import adminfrom django.urls import path, include, re_pathfrom rest_framework import routersfrom rest_framework_swagger.views import get_swagger_viewschema_view = get_swagger_view(title='api list')router = routers.DefaultRouter()urlpatterns = [   re_path(r'^', include(router.urls)),   path('admin/', admin.site.urls),   path('schema/', schema_view),   # 添加schema模式   re_path(r'^bm/', include('apps.bm.urls')),   # 添加bm/urls.py的路径。]
5服务启动和测试

配置好开发的bm应用之后,在启动Django服务之前还需要创建bm数据库表、超级用户等信息,然后才能进行测试。依次执行以下命令创建数据库表:

python manage.py makemigrations bm  # 在bm模块下生成migrations文件夹,包含0001_initial.py文件

python manage.py migrate bm   # 将0001_initial.py的变更更新到数据库中。

python manage.py test  # 执行单元测试,单元测试是保证实现的接口没有问题一个很重要的手段,有单元测试,很多的bug都可以在单元测试阶段发现

python manage.py createsuperuser  # 输入交互命令并按提示输入用户名,邮箱和密码

python manage.py runserver   #  启动Django服务

启动成功后,可以看到如下信息: 3ff499067bd404639957211d99a83bc5.png

打开http://127.0.0.1:8000/admin/ 并输入刚才创建的用户名和密码,可以看到创建的bm数据表。           77288789c74aa06029f952bc150fe824.png

这是Django的后台服务,看到的表的字段等信息在admin.py中定义(不一定更跟真实的数据表字段一致),这里可以手动对表进行crud操作。数据库“AUTHENTICATION AND AUTHORIZATION”和“AUTH TOKEN”的功能会在后续文章中介绍。

Django还提供了schema模式(通过api对数据库进行操作),地址为:http://127.0.0.1:8000/schema/           25cb3f38fac4d9174e360a46a7a76fdc.png

这个页面的url在urls.py中定义,是标准的restful api,外部用户即可通过这些url来访问数据库。比如我们需要添加一个author记录,则选择post /bm/author/这一项,点开之后,即可通过url来添加记录:             e71ad416cf12ed170540567bc7b5aa3a.png      其他的get,put,patch,delete等方法可以依次测试。到目前为止,这里就完成了使用Django管理数据库应用开发,其他相关的应用开发后续会陆续介绍。

6

总结

本文从最基础的起点介绍Django的使用,先简要介绍了Django在web框架中的地位,然后介绍了Django的应用开发环境准备,接着介绍了添加书籍管理应用的开发和配置,最后介绍了书籍管理应用的部署和启动。

在后续的文章中,会更深入的剖析Django的内部实现原理,比如migrate的原理(ORM机制),权限控制机制等等。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值