首页 > 编程知识 正文

python有什么用,python实战一个完整的项目

时间:2023-05-03 05:50:14 阅读:141188 作者:4983

作者: kinegratii

资料来源: https://kinegratii.github.io/2017/07/31/django-full-stack-note /

概要

BWS项目是自己开发了一年的项目。 本文对项目中的一些技术选型、功能实现、项目流程进行了简要总结。

python3

虽然Python3发布已经有10年了,但2与3之争今天依然存在,对于如何学习,每个人都有自己的理解和学习策略。 我个人的看法:勇于面向未来学习3;

3和2的区别对学习过程影响不大,掌握了3自然就能很快上手2;

大多数常见的第三方库(80%以上)都支持Python3

但在系统安装过程中始终存在23个,可以自由切换;

今年4月重新开发时,采取了完全放弃对Python2的支持的比较激进的做法。 当时的想法是将该项目作为Django持续学习的示范项目,但最终Django的下一个主要版本2.0 (预定2017年12月发布) )也要求最低版本3.5。

实际上,在项目中使用一些Python2不支持的语法和没有的标准库就可以达到上述目的。 具体来说,在代码中使用了以下语法。 词典合并成文法(PEP448 )。

强制关键字参数(PEP3102 ) ) ) ) )。

根据PEP448,Python3.5允许您使用更简洁、更易于理解的代码合并多个词典。

# 3.5

combination={ * * first _ dictionary,' x':1,' y':2}

# 3.5以下

combination=first _ dictionary.copy (

combination.update({'x':1,' y':2} )

另外,Python3在文本和二进制方面有了比较大的变化,这给文件的导入导出功能的开发带来了便利,可以集中解决业务层面的问题,而不用在意2的编码问题。

Django

我也是Django的忠实用户。 从1.4到1.11被使用,继续看着Django的成长和成长。 1.4/1.8/1.11是LTS版本,项目使用的是1.10。 近几年来,Django的一大改变是定制用户类型。 这是1.5中的一个功能,以前只能使用内置的用户类,使用邮箱作为用户名也无法直接支持。

数据库迁移:参考1.7south实现。 这是开发的利器,修改用户模型时,可以忽略特定的数据库类型,使用命令一键将修改同步到数据库。

自定义筛选器查询: 1.7,它主要用于封装某些业务数据库查询。

多模板支持: 1.8中引入的Django自身模板引擎效率一直以来备受人们诟病,但现在Django可以使用类似Jinja2的模板。

表单控件支持模板呈现。 Django表单实际上侧重于后端验证,前端相对较弱,定制不是那么容易。 可以从最新1.11版中引入的模板文件中自定义控件样式等。

CBV

强烈建议使用基于类的视图来组织视图处理函数。

Class-Based-View对于Function-Based-View主要支持封装,减少重复的代码编写工作,逻辑流程清晰且经过测试。 具体来说,要编写代码,您需要检查源代码并了解其功能实现。

CBV的核心是最小模式。 Mixin是一种组合利用多个类中功能单元的方式,这听起来像是有类继承机制就可以实现,但这与传统的类继承不同。 通常,mixin作为任何类的基类,都不关心与哪个类一起使用,而是在运行时动态地与其他零散类组合使用。

使用mixin机制具有在不更改源代码的情况下扩展现有类的优点。 根据能够保证组件划分的需要,可以组合现有功能以实现“新”类; 由于新的业务需求可能需要创建新的子类,因此可以避免类继承的限制。

现在视图函数也几乎不写了。 在项目中可以看到django.contrib.auth.login等几个函数,现在改为视图类格式。

是否启用管理员

admin是Django的主要优点,但其使用场景有限,主要集成了寻呼、过滤、搜索、增删校验、批量操作等多种功能,因此相互之间有非常高的耦合度。 在不提供公开的API的情况下实现定制往往是“牵一发而动全身”,最后基本上会改变面貌。

由于项目没有使用内置的admin组件,因此要添加或删除检查过的页面,需要花一点时间让其自己适应。

日志模型也必须自己设计。 我自己在项目中添加了一个名为ip的字段。 这个本来就没有。

后端数据API - DRF

后端数据采用Django Rest Framework这一框架,涵盖了搜索/分页等大多数需求

访问权限

请求限制(频率、IP ) )。

表单验证

前端照片用户界面

前端UI使用一个名为Amaze UI的框架。 但从后来的发展情况来看,这是

是最为错误的决定了,主要原因在于无法和后端比较平稳地整合。

Django表单中有一个比较大的问题,如何需要定制控件样式,需要在Python代码中修改,而且需要应用的每一处都需要更改,灵活度不够。目前主要有两种解决方式:使用Django1.11版本的模板功能,这个功能刚刚推出,文档也只有一页的内容,不太建议使用。

使用 django-crispy-forms 第三方库,这个库的思路也是使用模板html文件渲染控件,已经有一定的使用规模,但是支持 Bootstrap这样常见的UI框架,不支持 Amaze UI。

导入导出

实现导入导出功能主要使用的是 tablib 和 django-import-export 这两个库,其中后者依赖前者。

导出

编写 Resource, 几点值得注意的地方:需要设置表头,不仅需要指定字段 Meta.fields,同时也要显示指定 Meta.export_order的值,通常和 Meta.fields一样即可。

Meta.fields 里的元素必须是模型的数据库字段,不能是自定义的 property,这一点和 ModelAdmin.list_display 不一样。

可以使用 dehydrate_FOO 函数重写导出内容

class BillResource(resources.ModelResource):defget_export_headers(self):

return['流水号','月份','类型','单价','用量','金额']

defdehydrate_price(self,obj):

returnobj.get_price_display

classMeta:

model=models.Bill

fields=('id','month','resource_type','price','amout','total')

export_order=fields

导入

django-import-export也提供了几个Mixin,但问题这些和admin组件耦合很高,不利于一些自定义操作,所以直接使用tablib库比较好。根据官方文档,可以使用以下代码实现文件导入

imported_data=Dataset().load(open('data.csv').read())

但其实load还有几个比较重要的参数:format:文件格式,如果不写,使用自动识别,但有出错的机率,之前试验过一个xlsx文件在不同环境下识别为json文件的,因此建议这个参数也留给用户输入

headers:表示第一行是否是表头,这个参数在文档中没有表明,需要自行查看源代码获取相关信息。

所以最后就写成下面这个样子

classBillUploadForm(form.Form):

import_file=forms.FileField()

format=forms.ChoiceField(choices=(('xlsx','xlsx'),('xls','xls')))

# 导入

tablib.Dataset().load(form.cleaned_data['import_file'].read(),format=form.cleaned_data['format'],headers=False)

数据库查询优化

select_related函数

selectrelated是 django.db.models.QuerySet 类的一个方法,它解决了 ORM中常见的N+1查询效率问题,关于这一部分可以参考我之前写过的一篇文章《selectrelated函数性能基本测试》。

更新记录

在更新记录时可以使用 update_fields 参数指定只需更新的字段列表。这个参数在只更新一两个字段的时候特别有用。

product.name='Name changed again'

product.save(update_fields=['name'])

如果不指定参数的值,将更新所有字段。

测试和部署

分离配置文件

Django使用 settings 模块配置相关参数,这使得其很好的区分开发/测试/生产。

-BillWorkingSystem

-BillWorkingSystem

-__init__.py

-settings.py

-test_settings.py

-urls.py

-wsgi.py

一个简单的testsettings.py如下,可以配置一些仅用于测试的项目,如数据目录 FIXTUREDIRS 。

fromBillWorkingSystem.settingsimport*

classDisableMigrations(object):

def__contains__(self,item):

returnTrue

def__getitem__(self,item):

return'notmigrations'

MIGRATION_MODULES=DisableMigrations()

FIXTURE_DIRS=(

os.path.join(BASE_DIR,'fixtures').replace('', '/'),

)

UPLOAD_TEST_DATA_DIR = os.path.join(BASE_DIR, 'fixtures', 'test_data').replace('','/')

MIGRATION_MODULES 设置表示是否运行数据迁移脚本。上述例子设置为空,表示测试无需运行这些迁移脚本。

单元测试

单元测试主要测试那些返回为实际数据(如json/yaml)的视图。

测试采用标准的 django.test.TestCase,按照文档所描述的步骤,一步一步的编写。

classBillCreateTestCase(TestCaseBase):

url='/api/bill/create/'

deftest_success(self):

data={

'enterprise':1,

'year':2017,

'month':1,

'amount':4000,

'create_name':'Test'

}

rsp=self.client.post(self.url,data)

self.assertEqual(201,rsp.status_code)

# 其他assert语句

deftest_with_error_enterprise(self):

data={}# 参数

rsp=self.client.post(self.url,data)

self.assertEqual(400,rsp.status_code)

# 其他assert语句

一个基本模式,一个TestCase表示一个主要功能,如一个POST请求

每个 test_FOO 函数表示一种情况,包括正确和无效参数

依次对响应对象的状态码和内容、数据变更进行断言(Assert)测试

docker部署

之前采用的是daocloud这个平台的工具。具体可参考《使用DaoCloud部署Django项目》这篇文章。由于对docker这方面没有一个完整的学习,加上daocloud.io更新到3版本,作了一些比较大的改变,后来就决定搬迁到阿里云服务器上,这样相对比较容易把握。

后记

轮子

什么是轮子 wheel,写多了代码就会发现一些代码具有共同之处,将其抽象并提取,慢慢地就形成了一个库,可以和别人分享。本质上来说,Django也是一个轮子。

持续开发

由于是个人项目,因此一些版本升级方面就比较随意,基本上新版本出来就完全废弃旧有版本。

第三方库

稳定才是真,不要为追求标新立异而盲目升级。

题图:pexels,CC0 授权。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。