跳转到内容

Django代码风格

来自代码酷
Admin留言 | 贡献2025年5月1日 (四) 01:48的版本 (Page creation by admin bot)

(差异) ←上一版本 | 已核准修订 (差异) | 最后版本 (差异) | 下一版本→ (差异)

Django代码风格[编辑 | 编辑源代码]

Django代码风格是指在使用Django框架开发Web应用时,遵循的一系列编码规范和最佳实践。良好的代码风格不仅能提高代码可读性,还能促进团队协作,减少维护成本。本指南将详细介绍Django官方推荐和社区广泛接受的代码风格规范。

介绍[编辑 | 编辑源代码]

Django作为一个成熟的Python Web框架,其代码风格主要基于PEP 8(Python的官方风格指南),同时结合框架自身特点形成了一些特定约定。这些规范涉及:

  • 项目结构组织
  • 命名约定
  • 代码布局
  • 模型设计
  • 视图编写
  • 模板处理
  • 测试规范

项目结构[编辑 | 编辑源代码]

标准的Django项目应遵循以下目录结构:

myproject/
├── manage.py
├── myproject/
│   ├── __init__.py
│   ├── settings/
│   │   ├── __init__.py
│   │   ├── base.py
│   │   ├── development.py
│   │   └── production.py
│   ├── urls.py
│   └── wsgi.py
├── apps/
│   └── myapp/
│       ├── __init__.py
│       ├── admin.py
│       ├── apps.py
│       ├── migrations/
│       ├── models.py
│       ├── tests.py
│       ├── urls.py
│       └── views.py
└── requirements/
    ├── base.txt
    ├── development.txt
    └── production.txt

关键特点:

  • 使用Python包组织项目(包含__init__.py
  • 将settings拆分为多个环境专用文件
  • 应用存放在专门的apps/目录
  • 依赖管理分环境存储

命名约定[编辑 | 编辑源代码]

文件和目录[编辑 | 编辑源代码]

  • 使用小写字母和下划线(snake_case)
  • 模板目录:templates/app_name/
  • 静态文件目录:static/app_name/

Python标识符[编辑 | 编辑源代码]

Django命名规范对照表
类型 规范 示例
小写+下划线 | views.py
大驼峰 | class BlogPost
小写+下划线 | get_absolute_url()
大写+下划线 | MAX_POSTS = 100

代码组织[编辑 | 编辑源代码]

模型设计[编辑 | 编辑源代码]

from django.db import models
from django.urls import reverse

class Article(models.Model):
    """博客文章模型"""
    title = models.CharField(
        max_length=200,
        verbose_name="标题",
        help_text="请输入文章标题"
    )
    content = models.TextField()
    pub_date = models.DateTimeField(auto_now_add=True)
    author = models.ForeignKey(
        'auth.User',
        on_delete=models.CASCADE,
        related_name='articles'
    )

    class Meta:
        ordering = ['-pub_date']
        verbose_name_plural = "文章"

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return reverse('article_detail', args=[str(self.id)])

最佳实践:

  • 每个字段单独一行
  • 添加verbose_namehelp_text
  • 定义__str__方法
  • 使用related_name明确反向关系
  • 添加get_absolute_url方法

视图编写[编辑 | 编辑源代码]

from django.views.generic import ListView, DetailView
from .models import Article

class ArticleListView(ListView):
    """文章列表视图"""
    model = Article
    template_name = 'blog/article_list.html'
    context_object_name = 'articles'
    paginate_by = 10

    def get_queryset(self):
        """重写查询集添加过滤条件"""
        return super().get_queryset().filter(
            is_published=True
        ).select_related('author')

模板处理[编辑 | 编辑源代码]

{# blog/article_detail.html #}
{% extends "base.html" %}

{% block title %}{{ article.title }}{% endblock %}

{% block content %}
<article>
  <h1>{{ article.title }}</h1>
  <p class="meta">
    作者: {{ article.author.username }} | 发布于 {{ article.pub_date|date:"Y-m-d" }}
  </p>
  <div class="content">
    {{ article.content|linebreaks }}
  </div>
</article>
{% endblock %}

测试规范[编辑 | 编辑源代码]

from django.test import TestCase
from django.urls import reverse
from .models import Article

class ArticleModelTest(TestCase):
    @classmethod
    def setUpTestData(cls):
        """创建测试数据"""
        cls.article = Article.objects.create(
            title="测试标题",
            content="测试内容"
        )

    def test_title_max_length(self):
        """测试标题最大长度"""
        max_length = self.article._meta.get_field('title').max_length
        self.assertEqual(max_length, 200)

    def test_article_str(self):
        """测试__str__方法"""
        self.assertEqual(str(self.article), "测试标题")

class ArticleViewTest(TestCase):
    def test_view_url_exists(self):
        """测试视图URL可访问"""
        response = self.client.get('/articles/')
        self.assertEqual(response.status_code, 200)

安全实践[编辑 | 编辑源代码]

查询安全[编辑 | 编辑源代码]

# 不安全
Article.objects.raw("SELECT * FROM blog_article WHERE title = '%s'" % user_input)

# 安全
Article.objects.filter(title=user_input)

表单处理[编辑 | 编辑源代码]

from django import forms
from django.core.exceptions import ValidationError

class CommentForm(forms.Form):
    name = forms.CharField(max_length=100)
    email = forms.EmailField()
    content = forms.CharField(widget=forms.Textarea)

    def clean_content(self):
        content = self.cleaned_data['content']
        if len(content) < 10:
            raise ValidationError("评论太短")
        return content

性能优化[编辑 | 编辑源代码]

graph TD A[请求到达] --> B[缓存检查] B -->|命中| C[返回缓存] B -->|未命中| D[数据库查询] D --> E[模板渲染] E --> F[缓存结果] F --> G[返回响应]

关键优化点:

  • 使用select_relatedprefetch_related
  • 合理使用缓存
  • 延迟加载不必要的数据
  • 批量操作代替循环

代码格式化工具[编辑 | 编辑源代码]

推荐工具组合:

  • black - 自动格式化代码
  • flake8 - 检查PEP 8合规性
  • isort - 自动排序import语句

配置示例(pyproject.toml):

[tool.black]
line-length = 88
target-version = ['py38']
include = '\.pyi?$'
exclude = '''
/(
    \.git
  | \.hg
  | \.mypy_cache
  | \.tox
  | \.venv
  | _build
  | buck-out
  | build
  | dist
)/
'''

[tool.isort]
profile = "black"
multi_line_output = 3
include_trailing_comma = true
force_grid_wrap = 0
use_parentheses = true
ensure_newline_before_comments = true
line_length = 88

实际案例[编辑 | 编辑源代码]

电商平台商品模块代码风格示例:

from django.db import models
from django.utils.translation import gettext_lazy as _

class Product(models.Model):
    """商品核心模型"""
    name = models.CharField(
        max_length=255,
        verbose_name=_("商品名称")
    )
    sku = models.CharField(
        max_length=50,
        unique=True,
        verbose_name=_("库存单位")
    )
    price = models.DecimalField(
        max_digits=10,
        decimal_places=2,
        verbose_name=_("价格")
    )
    description = models.TextField(
        blank=True,
        verbose_name=_("商品描述")
    )
    category = models.ForeignKey(
        'Category',
        on_delete=models.PROTECT,
        related_name='products',
        verbose_name=_("商品分类")
    )
    is_active = models.BooleanField(
        default=True,
        verbose_name=_("是否上架")
    )

    class Meta:
        verbose_name = _("商品")
        verbose_name_plural = _("商品")
        ordering = ['name']

    def __str__(self):
        return f"{self.name} ({self.sku})"

    def get_absolute_url(self):
        return reverse('product_detail', kwargs={'pk': self.pk})

总结[编辑 | 编辑源代码]

遵循Django代码风格的主要优势:

  • 提高代码可读性和一致性
  • 减少团队协作中的摩擦
  • 便于维护和扩展
  • 降低引入安全漏洞的风险
  • 优化应用性能

建议开发者: 1. 始终遵循PEP 8基础规范 2. 使用Django内置工具和约定 3. 保持代码风格一致性 4. 定期使用代码检查工具 5. 编写清晰的文档字符串

通过遵循这些最佳实践,您可以构建出更健壮、更易维护的Django应用程序。