美文网首页19-23年 学习笔记
【Django框架】学习笔记

【Django框架】学习笔记

作者: Du1in9 | 来源:发表于2020-07-17 11:32 被阅读0次
    • 什么是Django
    • 浏览器上网的基本原理
    • 环境配置

    Python3.7安装
    https://www.python.org/ftp/python/3.7.8/python-3.7.8-amd64.exe
    Django安装
    python37 -m pip install Django
    Conda安装
    https://blog.csdn.net/ITLearnHall/article/details/81708148
    PyCharm IDE安装与激活
    https://docs.qq.com/doc/DR3Z3aXlxYUZMRFFp

    • Django命令

    启动一个项目:startproject
    启动一个应用:startapp
    检查项目完整:check
    本地运行项目:runserver
    执行用例测试:test
    创建迁移文件:makemigrations
    执行迁移文件:migrate
    进入Python Shell环境:shell
    把数据库数据导出到文件:dumpdata
    把文件数据导入到数据库:loaddata

    • 初识项目

    django-admin startproject django_introduction

    settings.py:项目配置文件
    urls.py:路由配置文件
    wsgi.py:wsgi应用的文件内容

    python37 manage.py runserver

    • 初识应用

    Django应用 vs Django项目

    python37 manage.py startapp blog

    应用目录

    • Django视图 & Django路由

    设置解释器为python3.7

    views.py

    from django.http import HttpResponse
    
    
    def hello_world(request):
        return HttpResponse("hello world")
    

    blog.urls.py

    from django.urls import path, include
    import blog.views
    
    urlpatterns = [
        path('hello_world', blog.views.hello_world)
    ]
    

    django_introduction.urls.py

    from django.contrib import admin
    from django.urls import path, include
    
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('blog/', include('blog.urls'))
    ]
    

    settings.py

    INSTALLED_APPS = [
    
        ...
    
        'blog.apps.BlogConfig'
    ]
    
    • 模型层
    • 创建博客文章模型

    models.py

    from django.db import models
    
    
    class Article(models.Model):
        # 文章ID
        article_id = models.AutoField(primary_key=True)
        # 文章标题
        title = models.TextField()
        # 文章摘要
        brief_content = models.TextField()
        # 文章内容
        content = models.TextField()
        # 文章日期
        publish_date = models.DateTimeField(auto_now=True)
    

    python37 manage.py makemigrations

    python37 manage.py migrate

    • 初识Django Shell

    python37 manage.py shell

    >>> from blog.models import Article
    >>> a =Article()
    >>> a.title = 'Django Test Shell'
    >>> a.digest = 'Giao'
    >>> a.content = 'Django Test Main content'
    >>> a.save()
    >>> print(a)
    Article object (1)
    >>> print(a.title)
    Django Test Shell
    
    >>> all = Article.objects.all()
    >>> x = all[0]
    >>> print(a.content)
    Django Test Main content
    
    • 初识Django Admin模块

    创建管理员

    python37 manage.py createsuperuser

    Username (leave blank to use 'yydl'): Du1in9
    Email address:
    Password:
    Password (again):
    Superuser created successfully.
    

    admin.py

    from django.contrib import admin
    from blog.models import Article
    
    admin.site.register(Article)
    

    python37 manage.py runserver

    访问登录:http://127.0.0.1:8000/admin/

    为了看到标题,models.py新增语句

        def __str__(self):
            return self.title
    

    新建文章,Ctrl+C关闭,重启

    • 实现博客数据返回页面

    views.py

    from blog.models import Article
    
    ...
    
    def article_content(request):
        article = Article.objects.all()[0]
        title = article.title
        brief_content = article.brief_content
        content = article.content
        article_id = article.article_id
        publish_date = article.publish_date
        
        return_str = 'title: %s, brief_content: %s, content: %s, article_id: %s, publish_date: %s' % (title, brief_content, content, article_id, publish_date)
        return HttpResponse(return_str)
    

    blog.urls.py

        path('content', blog.views.article_content)
    

    python37 manage.py runserver

    访问:http://127.0.0.1:8000/blog/content

    • 使用Bootstrap实现静态博客页面

    Bootstrap官网:https://v3.bootcss.com/

    templates.index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>一给我里GiaoGiao</title>
        <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
        <!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
        <script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
    </head>
    <body>
    <div class="container page-header">
        <h1>
            BootCDN简介 <small> —— by Du1in9 </small>
        </h1>
    </div>
    <div class="container page-body">
        <div class="col-md-9" role="main">
            <div class="body-main">
                <div>
                    <h2>文章标题1</h2>
                    <p>
                        Vue 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。
                        Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。
                    </p>
                    <p>
                        jQuery 是一个高效、精简并且功能丰富的 JavaScript 工具库。它提供的 API 易于使用且兼容众多浏览器,
                        这让诸如 HTML 文档遍历和操作、事件处理、动画和 Ajax 操作更加简单。
                    </p>
                </div>
                <div>
                    <h2>文章标题2</h2>
                    <p>
                        ECharts 是一个使用 JavaScript 实现的开源可视化库,可以流畅的运行在 PC 和移动设备上,
                        兼容当前绝大部分浏览器(IE8/9/10/11,Chrome,Firefox,Safari等),底层依赖轻量级的矢量图形库 ZRender,
                        提供直观,交互丰富,可高度个性化定制的数据可视化图表。
                    </p>
                    <p>
                        Backbone 为复杂 Javascript 应用程序提供模型(models)、集合(collections)、视图(views)的结构。
                        其中模型用于绑定键值数据和自定义事件;集合附有可枚举函数的丰富 API;
                        视图可以声明事件处理函数,并通过 RESTful JSON 接口连接到应用程序。
                    </p>
                </div>
            </div>
        </div>
        <div class="col-lg-3" role="complementary">
            <h2>最新新闻</h2>
            <h4><a href="#">最新新闻1</a> </h4>
            <h4><a href="#">最新新闻2</a> </h4>
            <h4><a href="#">最新新闻3</a> </h4>
            <h4><a href="#">最新新闻4</a> </h4>
            <h4><a href="#">最新新闻5</a> </h4>
            <h4><a href="#">最新新闻6</a> </h4>
            <h4><a href="#">最新新闻7</a> </h4>
            <h4><a href="#">最新新闻8</a> </h4>
            <h4><a href="#">最新新闻9</a> </h4>
            <h4><a href="#">最新新闻10</a> </h4>
        </div>
    </div>
    </body>
    </html>
    

    templates.detail.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Django Web框架入门</title>
        <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css"
              integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
        <!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
        <script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js"
                integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
                crossorigin="anonymous"></script>
    </head>
    <body>
    <div class="container page-header">
        <h1>文章标题1
        </h1>
    </div>
    <div class="container body-main">
        <div>
            <p>
                在有些场合,需要对Django处理的每个request都执行某段代码。 这类代码可能是在view处理之前修改传入的request,或者记录日志信息以便于调试,等等。2
    
                这类功能可以用Django的中间件框架来实现,该框架由切入到Django的request/response处理过程中的钩子集合组成。
                每个中间件组件都用于某个特定的功能。 如果你是顺着这本书读下来的话,你应该已经多次见到“中间件”了
    
                第12章中所有的session和user工具都籍由一小簇中间件实现(例如,由中间件设定view中可见的 request.session 和 request.user )。
    
                第13章讨论的站点范围cache实际上也是由一个中间件实现,一旦该中间件发现与view相应的response已在缓存中,就不再调用对应的view函数。
    
                第14章所介绍的 flatpages , redirects , 和 csrf
                等应用也都是通过中间件组件来完成其魔法般的功能。这个轻量级低层次的plug-in系统,能用于全面的修改Django的输入和输出。1
    
            </p>
            <p>
                每个中间件组件都用于某个特定的功能。 如果你是顺着这本书读下来的话,你应该已经多次见到“中间件”了
    
                第12章中所有的session和user工具都籍由一小簇中间件实现(例如,由中间件设定view中可见的 request.session 和 request.user )。
    
                第13章讨论的站点范围cache实际上也是由一个中间件实现,一旦该中间件发现与view相应的response已在缓存中,就不再调用对应的view函数。
    
                第14章所介绍的 flatpages , redirects , 和 csrf 等应用也都是通过中间件组件来完成其魔法般的功能。
            </p>
        </div>
    </div>
    
    </body>
    </html>
    
    • 模板系统基本语法

    变量标签:{{ x }}
    for循环标签:{% for x in list %},{% endfor %}
    if-else分支标签:{% if %},{% else %},{% endif %}

    templates.template.html

    <html>
    <head><title>Ordering notice</title></head>
    
    <body>
    
    <h1>Ordering notice</h1>
    
    <p>Dear {{ person_name }},</p>
    
    <p>Thanks for placing an order from {{ company }}. It's scheduled to
        ship on {{ ship_date|date:"F j, Y" }}.</p>
    
    <p>Here are the items you've ordered:</p>
    
    <ul>
        {% for item in item_list %}
        <li>{{ item }}</li>
        {% endfor %}
    </ul>
    
    {% if ordered_warranty %}
    <p>Your warranty information will be included in the packaging.</p>
    {% else %}
    <p>You didn't order a warranty, so you're on your own when
        the products inevitably stop working.</p>
    {% endif %}
    
    <p>Sincerely,<br/>{{ company }}</p>
    
    </body>
    </html>
    
    • 模板系统渲染页面

    使用以下脚本导入data.article的多篇文章

    import os
    import django
    
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'django_introduction.settings')
    django.setup()
    
    from blog.models import Article
    
    data_path = '../data/article'
    
    
    def main():
        content_list = []
        files = os.listdir(data_path)
        for name in files:
            f = os.path.join(data_path, name)
            with open(f, 'r', encoding='utf-8') as f:
                content = f.read()
                item = (name[:-4], content[:100], content)
                content_list.append(item)
        # Article.objects.all().delete()
        for item in content_list:
            print('saving article: %s' % item[0])
            article = Article()
            article.title = item[0]
            article.brief_content = item[1]
            article.content = item[2]
            article.save()
    
    
    if __name__ == '__main__':
        main()
    

    templates.index.html

    <div class="container page-body">
        <div class="col-md-9" role="main">
            <div class="body-main">
                {% for article in article_list %}
                <div>
                    <h2><a href="#">{{ article.title }}</a></h2>
                    <p>{{article.digest}}</p>
                </div>
                {% endfor %}
            </div>
        </div>
        <div class="col-md-3" role="complementary">
            <div>
                <h2>最新文章</h2>
                {% for article in article_list %}
                <h4><a href="#">{{ article.title }}</a></h4>
                {% endfor %}
            </div>
        </div>
    </div>
    

    templates.detail.html

    <div class="container page-header">
        <h1>{{ curr_article.title }}
        </h1>
    </div>
    
    <div class="container body-main">
        <div>
            {% for section in section_list %}
            <p>{{ section }}</p>
            {% endfor %}
        </div>
    </div>
    

    views.py

    from django.shortcuts import render
    
    ...
    
    def get_index_page(request):
        all_article = Article.objects.all()
        return render(request, 'blog/index.html',
                      {
                          'article_list':all_article
                      }
                      )
    
    
    def get_detail_page(request):
        curr_article = Article.objects.all()[1]
        section_list = curr_article.content.split('\n')
        return render(request, 'blog/detail.html',
                      {
                          'curr_article': curr_article,
                          'section_list': section_list
                      }
                      )
    

    blog.urls.py

        path('index', blog.views.get_index_page),
        path('detail', blog.views.get_detail_page)
    
    • 实现页面的跳转

    1)指定id跳转文章详情页

    urls.py

        # path('detail', blog.views.get_detail_page),
        path('detail/<int:article_id>', blog.views.get_detail_page)
    

    views.py

    def get_detail_page(request, id):
        all_article = Article.objects.all()
        curr_article = None
        for article in all_article:
            if article.article_id == article_id:
                curr_article = article
                break
    

    2)主页跳转文章详情页

    index.html

                    <h2><a href="/blog/detail/{{article.article_id}}">{{ article.title }}</a></h2>
    ...
                <h4><a href="/blog/detail/{{article.article_id}}">{{ article.title }}</a></h4>
    
    • 实现上下篇文章跳转

    detail.html

    <div>
        <nav aria-label="...">
      <ul class="pager">
        <li><a href="/blog/detail/{{ previous_article.article_id }}">上一篇:{{ previous_article.title }}</a></li>
        <li><a href="/blog/detail/{{ next_article.article_id }}">下一篇:{{ next_article.title }}</a></li>
      </ul>
    </nav>
    </div>
    

    views.py

    def get_detail_page(request, article_id):
        all_article = Article.objects.all()
        curr_article = None
        previous_article = None
        next_article = None
        previous_index = 0
        next_index = 0
    
        for index, article in enumerate(all_article):
            # 前面
            if index == 0:
                previous_index = 0
                next_index = index + 1
            # 后面
            elif index == len(all_article) - 1:
                previous_index = index - 1
                next_index = index
            # 中间
            else:
                previous_index = index - 1
                next_index = index + 1
            # article
            if article.article_id == article_id:
                curr_article = article
                previous_article = all_article[previous_index]
                next_article = all_article[next_index]
                break
    
        ...
    
                          'previous_article': previous_article,
                          'next_article': next_article
    
    • 实现分页功能

    1)主页按钮

    index.html

    <div class="body-footer">
      <div class="col-md-4 col-md-offset-3">
        <nav aria-label="Page navigation">
          <ul class="pagination">
            <li>
              <a href="#" aria-label="Previous">
                <span aria-hidden="true">&laquo;</span>
              </a>
            </li>
              <li><a href="#">1</a></li>
              <li><a href="#">2</a></li>
              <li><a href="#">3</a></li>
              <li><a href="#">4</a></li>
              <li><a href="#">5</a></li>
            <li>
           <a href="#" aria-label="Next">
            <span aria-hidden="true">&raquo;</span>
          </a>
        </li>
      </ul>
    </nav>
    

    2)设计分页的url

    views.py

    def get_index_page(request):
        page = request.GET.get('page')
        if page:
            page = int(page)
        else:
            page = 1
        print('page param: ', page)
    

    访问http://127.0.0.1:8000/blog/index?page=2,再看终端

    用shell调试Django分页功能

    >>> from django.core.paginator import Paginator
    >>> l = [1,2,3,4,5]
    >>> p = Paginator(l,2)
    >>> p.num_pages
    3
    >>> p.count
    5
    >>> p1 = p.page(1)
    >>> p2 = p.page(2)
    >>> p1.object_list
    [1, 2]
    >>> p2.object_list
    [3, 4]
    >>> p2.has_next()
    True
    >>> p1.has_previous()
    False
    >>>
    

    views.py

    def get_index_page(request):
        # 获得参数
        page = request.GET.get('page')
        if page:
            page = int(page)
        else:
            page = 1
        print('page param: ', page)
        all_article = Article.objects.all()
        # 生成页面
        paginator = Paginator(all_article, 6)
        page_num = paginator.num_pages
        print('page num:', page_num)
        # 页面列表
        page_article_list = paginator.page(page)
        if page_article_list.has_next():
            next_page = page + 1
        # 最后
        else:
            next_page = page
        if page_article_list.has_previous():
            previous_page = page - 1
        # 最前
        else:
            previous_page = page
    
        return render(request, 'blog/index.html',
                      {
                          'article_list': page_article_list,
                          'page_num': range(1, page_num + 1),
                          'curr_page': page,
                          'next_page': next_page,
                          'previous_page': previous_page
                      }
                      )
    

    index.html

            <div class="body-footer">
                <div class="col-md-4 col-md-offset-3">
                    <nav aria-label="Page navigation">
                        <ul class="pagination">
                            <li>
                                <a href="/blog/index?page={{previous_page}}" aria-label="Previous">
                                    <span aria-hidden="true">&laquo;</span>
                                </a>
                            </li>
                            {% for num in page_num %}
                            <li><a href="/blog/index?page={{num}}">{{ num }}</a></li>
                            {% endfor %}
                            <li>
                                <a href="/blog/index?page={{next_page}}" aria-label="Next">
                                    <span aria-hidden="true">&raquo;</span>
                                </a>
                            </li>
                        </ul>
                    </nav>
                </div>
            </div>
    
    • 实现最近文章列表

    views.py

        top10_article_list = Article.objects.order_by('-publish_date')[:10]
    
        ...
    
                          'top10_article_list': top10_article_list
    

    index.py

                {% for article in top10_article_list %}
                <h4><a href="/blog/detail/{{article.article_id}}">{{ article.title }}</a></h4>
                {% endfor %}
    
    • 知识点总结

    相关文章

      网友评论

        本文标题:【Django框架】学习笔记

        本文链接:https://www.haomeiwen.com/subject/yaxghktx.html