设计模式

  • 定义

    # mysite/news/models.py
    
    from django.db import models
    
    class Reporter(models.Model):
        full_name = models.CharField(max_length=70)
    
        def __str__(self):
            return self.full_name
    
    class Article(models.Model):
        pub_date = models.DateField()
        headline = models.CharField(max_length=200)
        content = models.TextField()
        reporter = models.ForeignKey(Reporter, on_delete=models.CASCADE)
    
        def __str__(self):
            return self.headline
    
  • 应用

    $ python manage.py makemigrations
    
    $ python manage.py migrate
    
  • 调用非常的人性化, 像调用API一样的感觉。

    数据表里的每条记录就是一条对象,他的字段就是对象的属性

    # 从子应用 news 引用我们定义的模型
    
    >>> from news.models import Article, Reporter
    
    # 获取所有对象
    >>> Reporter.objects.all()
    <QuerySet []>
    
    # 新建一个 Reporter 对象
    >>> r = Reporter(full_name='John Smith')
    
    # 保存到数据库
    
    >>> r.save()
    
    # 自动生成的 id
    
    >>> r.id
    1
    
    >>> Reporter.objects.all()
    <QuerySet [<Reporter: John Smith>]>
    
    # 查看对象的属性
    
    >>> r.full_name
    'John Smith'
    
    # 通过 id 调用对象
    
    >>> Reporter.objects.get(id=1)
    <Reporter: John Smith>
    
    # 通过属性 full_name 调用对象
    
    >>> Reporter.objects.get(full_name__startswith='John')
    <Reporter: John Smith>
    
    >>> Reporter.objects.get(full_name__contains='mith')
    <Reporter: John Smith>
    
    >>> Reporter.objects.get(id=2)
    Traceback (most recent call last):
        ...
    DoesNotExist: Reporter matching query does not exist.
    
    # 新建一个 Article 对象
    
    >>> from datetime import date
    
    >>> a = Article(pub_date=date.today(), headline='Django is cool',
    ...     content='Yeah.', reporter=r)
    
    >>> a.save()
    
    
    >>> Article.objects.all()
    <QuerySet [<Article: Django is cool>]>
    
    # 调用 关联的 Reporter 对象
    
    >>> r = a.reporter
    >>> r.full_name
    'John Smith'
    
    # 反向调用
    
    >>> r.article_set.all()
    <QuerySet [<Article: Django is cool>]>
    
    # 查找发布者名字以 "John" 开头的文章 
    # Django 可以根据你的需要跟踪关系
    
    >>> Article.objects.filter(reporter__full_name__startswith='John')
    <QuerySet [<Article: Django is cool>]>
    
    # 修改属性 
    >>> r.full_name = 'Billy Goat'
    >>> r.save()
    
    # 删除对象
    >>> r.delete()
    
    
    

注册到管理站点

  • 又是非常人性的一点,只需写一行代码把写好的模型在 **admin.py 注册 **一下。

    我们就相当于写好了一个表的可视化 CRUD 后台。

  • 注册

    # mysite/news/admin.py
    
    from django.contrib import admin
    
    from . import models
    
    admin.site.register(models.Article)
    

规划 URLs

  • Django 的这个设计, 有利于将 Python 与 URL进行解耦** ( 各个模块分离、独立 )**。
    # mysite/news/usls.py
    
    from django.urls import path
    
    from . import views
    
    urlpatterns = [
        path('articles/<int:year>/', views.year_archive),
        path('articles/<int:year>/<int:month>/', views.month_archive),
        path('articles/<int:year>/<int:month>/<int:pk>/', views.article_detail),
    ]
    

编写视图

  • 视图就是上面 URLs 里的视图函数,函数从** URL 里获取前端传来的参数**进行逻辑处理。

    然后用数据对模(HTML)板渲染。返回。

  • 示例

    # mysite/news/views.py
    
    from django.shortcuts import render
    
    from .models import Article
    
    def year_archive(request, year):
        a_list = Article.objects.filter(pub_date__year=year)
        context = {'year': year, 'article_list': a_list}
        return render(request, 'news/year_archive.html', context)
    

设计模板

  • Django 中可以设置模板(HTML)路径便于检索, 减小模板之间的冗余。

    模板语言让 Python 和 HTML 动态的融合到一块。

    它还使用了 “模板继承” 的概念, 让新的模板在某个模板的基础上扩展。

    这样我们只需要写不一样的地方就可以了。

  • 示例

    # mysite/news/templates/news/year_archive.html
    
    {% extends "base.html" %}
    
    
    
    {% block title %}Articles for {{ year }}{% endblock %}
    
    {% block content %}
    <h1>Articles for {{ year }}</h1>
    
    {% for article in article_list %}
        <p>{{ article.headline }}</p>
        <p>By {{ article.reporter.full_name }}</p>
        
        # 模板过滤器 "|" ,将一个 Python datetime 对象转化为指定的格式
        <p>Published {{ article.pub_date|date:"F j, Y" }}</p> 
        
    {% endfor %}
    
    
    
    
    {% endblock %}