谈一谈django应用实践

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
简介: 谈一谈django应用实践

python 的 web 框架非常多,比较出名的有 django, flask, tornado。django 作为一个老牌框架,无论是文档还是代码质量都非常高,另外他自带的 admin 后台和一些有用的 app,如果你的需求是做 cms 之类的 web 应用的话,基本上不用开发多少代码就能出一个成品。不过很多新手可能一开始不太适应他的设计模式,遇到问题后基本就懵了,所以这里我按照自己用 django 的经验,写一下 django 的一些应用实践,可能写的比较零散,大家见谅。


整体流程1e4caadcfffd4146bacedec1bda6b63c.png

首先我们得了解下 django 这个框架整体的处理流程,假设我们采用 nginx + uwsgi + django 的 web server 模式


1. 一个请求过来后,首先经过 nginx 做反向代理,将请求转发到 uwsgi (python 用 wsgi 这种协议来解析 http 请求,uwsgi 是一个 解析 wsgi 的应用),uwsgi 再将解析过的数据传到 django。


2. django 收到请求后,首先会经过一组全局的中间件 (middleware),调用 process_request 作为预处理,比如解析用户状态,检验 csrf_token (post 请求),如果有问题,则直接返回 response,不再调用 view 函数。否则,调用 process_view ,如果没问题进入 view 函数。


3. 进入 view 函数后开发者可以写自己的逻辑,比如操作数据库,更新缓存,最后返回一个 response。


4. 接下来 跳出 view 函数,重新进入 middleware,调用 process_response,对 response 做些最后的修饰,返回给用户。


views 模块

1. view 不仅可以用函数,也可以用通用视图类(generic_view),好处是:代码更加清晰,可以复用继承,并且结合 mixin 能够开发更加灵活的 view 模块

def hello_fn(request, name="World"):
        return HttpResponse("Hellp {}!".format(name))
class FeedMixin(object):
        def get_context_data(self, **kwargs):
            context = super().get_context_data(**kwargs)
            context["feed"] = models.Post.objects.viewable_posts(self.request.user)
            return context
class MyFeed(FeedMixin, generic.CreateView):
        model = models.Post
        template_name = "myfeed.html"
        success_url = reverse_lazy("my_feed")
——————

2. python 的装饰器很好用,也可以用于 views 函数, 比如下面的装饰器用于登录用户的检测

@login_required
def simple_view(request):
       return HttpResponse()

urls 模块

1. urls.py 这个文件将访问的 url 跟 view 模块对应起来,按从上到下的顺序匹配

2. 采用 include 函数可以包含其他 app 的 urls,namespace 参数定义后可以在模板中直接调用,比如


{% url 'articles'%} 
url(r'^articles/$', include(articles.urls), namespace="articles"),


models 模块


1. model 是具有处理数据库的一种面向对象的方法的类,能够让不熟悉数据库语句的程序员也能快速操作数据库

2. 采用面向对象的方式创建类,加上 abstract = True 则为抽象类

class Postable(models.Model):
    created = models.DateTimeField(auto_now_add=True)
    modified = modified.DateTimeField(auto_now=True)
    message = models.TextField(max_length=500)
    class Meta:
        abstract = True
class Post(Postable):
    ...
class Comment(Postable):
   ···

3. django 表对应关系有一对一(OneToOneField),一对多 (ForeignKey),多对多 (ManyToManyField),其中 多对多的模式通过创建一个中间表来实现。

class Book(models.Model):
    place = models.OneToOneField(Place, primary_key=True)
    pub=models.ForeignKey(Publisher)
    authors=models.ManyToManyField(Author)


上面的例子中间表包括 author_id 和 book_id

4. django 的 signal 实现 hook 数据库写行为,比如,pre_save, post_save,pre_delete, post_delete,你也可以自定义 signal, hook 其他行为。

@receiver(post_save, sender=TransactionDetail, dispatch_uid="update_stock_count")
def update_stock(sender, instance, **kwargs):
     instance.product.stock -= instance.amount
     instance.product.save()


5. Person.objects.all(), 这里面的 objects 其实是个 manager, 实现了 all, filter 等函数,可以自定义

class Person(models.Model):
    object = models.Manager()

6. django 的 queryset 是惰性的,只有在真正用的时候才会去数据库查询,并且查询一次后,会有缓存,当再次遍历这个 queryset 的时候,不会再去查询。

person_set = Person.objects.filter(first_name="Dave")

7. 数据库第一次创建后,会有再次更新字段的需求。django 在 1.4 版本前并没有这个功能,得用第三方库 south 来更新,后来的版本 django 自带了 migration 功能,能够将最新的 model 版本和数据库的字段作对比,自动生成 migration 文件


python manage.py makemigrations # 生成 migration 文件
   python manage.py migrate # 将更改应用到数据库


8. orm 不能直接看到 raw sql 语句,可以通过如下语句查看 sql

from django.db import connection
connection.queries

9. 可以使用 django-debug-toolbar 插件查看慢查询,也能对对哪些页面载入较慢有个大致的了解。

10. 在 orm 中使用 select_related() 减少查询数据库次数:,select_related() 会自动扩展外键关系

class Province(models.Model):
    name = models.CharField(max_length=10)
class City(models.Model):
    name = models.CharField(max_length=5)
    province = models.ForeignKey(Province)
citys = City.objects.select_related().all()


不过对于高并发的应用来说外键不是很推荐。

forms 模块

1. 前端传上来一个表单的值,但是没法确认这些值是不是为空,是不是类型正确,这个时候当然可以自己一个个值判断,也可以采用 forms 模块去做验证,用过 django-rest-framework 的同学会知道和里面的 serializers 是同一个概念

class PersonDetailsForm(forms.Form):
       name = forms.CharField(max_length=100)
       age = forms.IntegerField()

2. 如果你用的是模板渲染的方式,那么展示的时候更简单,表单能自动生成 html 的表单。

>>> f = PersonDetailsForm()
>>> print(f.as_p())
<p><label for="id_name">Name:</label> <input id="id_name" maxlength="100"
name="name" type="text" /></p>
<p><label for="id_age">Age:</label> <input id="id_age" name="age"
type="number" /></p>

admin 模块

1. admin 基本上开箱即用,如果需要定制的话,也能做一些组件的定制,不过这些东西得看文档去详细了解了。


commands 模块

1. django 提供了后台脚本模块,可以自己集成 BaseCommand 类去自定义脚本

python mannage.py -h


这个命令就能看到所有的 commands 命令

2. 如果不想用他的模块,又想引入 django 项目的一些模块,可以采用下面的方法解决

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myproject.settings")
django.setup()

settings 模块


1. 所有的 settings 默认值都在这里面能找到,https://github.com/django/django/blob/master/django/conf/global_settings.py


2. 上线的时候记得把 DEBUG 改成 False, 然后加上 ALLOWED_HOSTS


3. MEDIA_ROOT, MEDIA_URL, STATIC_ROOT, STATIC_URL 这几个之前经常搞混,其实可以分为两类,MEDIA_ROOT 指的是上传文件的目录,MEDIA_URL 指的是前缀名,http://example.com/media/, 其中的media 就是 MEDIA_URL, 同样,STATIC_ROOT 指的是静态文件的目录,一般放 css, js 之类,STATIC_URL 值得是前缀名,http://example.com/static/


4. 一般部署上线的时候,用 nginx 直接渲染静态文件

location /media  {
        alias /root/example_project/public/media;
    }
    location /static {
        alias /root/example_project/static;
    }


contrib 模块


1. 这里面的模块是 django 自带的 apps,用的比较多的有 admin, auth, sessions


2. admin 模块其实就是 django 的后台


3. auth 模块就是用户模块,功能上比较齐全,基本上可以基于这个模块做扩展。


4. session 模块结合 auth ,用来做用户的登录状态,对于大型网站来说,session 的存储可能是个问题,django 也提供了不同的 backends,支持 db, cache, file 等存储方式。


middleware 模块


1. django 自带的 middlreware 对于普通网站的需求已经蛮完善了,比如 CsrfMiddleware , HttpMiddleware。


2. 如果有自己的需求,也可以自定义,比如记录详细 log 信息,LogMiddleware,还有跨域的 CorsMiddleware。


其他


1. 网上有人说 django 只能做小网站,不支持大的并发,其实这个说法还是很片面的。django 自身只是一个框架,如果网站请求处理慢,很多情况下是自己写的逻辑没有优化。确认是 django 框架问题的话,django 虽然设计上略复杂,但是很多模块还是可以拆分去自定义的。最后实在不济,靠增加机器数量也能顶一阵。


2. django 的国际化模块做的很不错


3. setting 文件可分成 product, 和 dev 两份,根据开发环境和生产环境不同引入不同的 setting 文件。


4. django-celery 用来执行异步任务


5. django 的插件非常多,rosarior/awesome-django







相关文章
|
26天前
|
存储 缓存 NoSQL
深入理解Django与Redis的集成实践
深入理解Django与Redis的集成实践
49 0
|
3月前
|
存储 监控 数据库
Django 后端架构开发:高效日志规范与实践
Django 后端架构开发:高效日志规范与实践
65 1
|
1月前
|
前端开发 JavaScript UED
探索Python Django中的WebSocket集成:为前后端分离应用添加实时通信功能
通过在Django项目中集成Channels和WebSocket,我们能够为前后端分离的应用添加实时通信功能,实现诸如在线聊天、实时数据更新等交互式场景。这不仅增强了应用的功能性,也提升了用户体验。随着实时Web应用的日益普及,掌握Django Channels和WebSocket的集成将为开发者开启新的可能性,推动Web应用的发展迈向更高层次的实时性和交互性。
64 1
|
24天前
|
IDE 关系型数据库 MySQL
Django学习一:创建Django框架,介绍Django的项目结构和开发逻辑。创建应用,编写主包和应用中的helloworld
这篇文章是关于如何创建一个Django框架,介绍Django的项目结构和开发逻辑,并指导如何创建应用和编写“Hello, World!”程序的教程。
34 3
Django学习一:创建Django框架,介绍Django的项目结构和开发逻辑。创建应用,编写主包和应用中的helloworld
|
25天前
|
监控 应用服务中间件 网络安全
部署Django应用:使用Gunicorn和Nginx构建高效的生产环境
部署Django应用:使用Gunicorn和Nginx构建高效的生产环境
96 0
|
25天前
|
存储 开发框架 JSON
【查漏补缺】Django模型字段类型及其应用
【查漏补缺】Django模型字段类型及其应用
14 0
|
26天前
|
存储 安全 UED
GitHub OAuth认证的Django应用
GitHub OAuth认证的Django应用
21 0
|
3月前
|
负载均衡 应用服务中间件 网络安全
Django后端架构开发:Nginx服务优化实践
Django后端架构开发:Nginx服务优化实践
57 2
|
3月前
|
中间件 数据库连接 UED
Django中间件秘籍:如何用几行代码让你的应用变得超级强大?
【8月更文挑战第31天】中间件是Django框架的核心特性,位于视图与HTTP服务器之间,允许全局处理请求和响应,增强Web应用功能。通过实现`MiddlewareMixin`类的方法,如`process_request`和`process_response`,可以轻松实现请求预处理或响应后处理。中间件应用场景广泛,包括用户认证、CSRF防护和数据库连接管理等。创建并配置中间件需将其加入`settings.py`的`MIDDLEWARE`列表,顺序决定执行优先级。合理利用中间件能提高代码重用性和应用性能,带来更好的用户体验。
51 0
|
3月前
|
JSON API 数据安全/隐私保护
Django 后端架构开发:JWT 项目实践与Drf版本控制
Django 后端架构开发:JWT 项目实践与Drf版本控制
63 0