• Django回顾之_02_Django的基本使用


    4. 虚拟环境

    4.1 概念

    之前安装python包的命令: sudo pip3 install 包名
    包的安装路径:/usr/local/lib/python3.5/dist-packages

    在同一个python环境中安装同一个包的不同版本,后安装的包会把原来安装的包覆盖掉。这样,如果同一台机器上两个项目依赖于相同包的不同版本,则会导致一些项目运行失败。
    解决的方案就是:虚拟环境。
    

    虚拟环境是真实python环境的复制版本。
    在虚拟环境中使用的python是复制的python,安装python包也是安装在复制的python中。

    4.2 安装和配置

    安装虚拟环境的命令:
    
    • 1)sudo pip install virtualenv #安装虚拟环境
    • 2)sudo pip install virtualenvwrapper #安装虚拟环境扩展包
    • 3)编辑/home目录下面的.bashrc文件,添加下面两行。
    export WORKON_HOME=$HOME/.virtualenvs
    source /usr/local/bin/virtualenvwrapper.sh
    
    • 4)使用source .bashrc使其生效一下。

    4.3 使用

    • 创建虚拟环境命令:mkvirtualenv 虚拟环境名
    • 创建python3虚拟环境:mkvirtualenv -p python3 evn_py3
      • 创建python3虚拟环境名,# 在创建虚拟环境时,必须保证有网
    • 进入虚拟环境工作:workon 虚拟环境名
    • 查看机器上有多少个虚拟环境:workon 空格 + 两个tab键
    • 退出虚拟环境:deactivate
    • 删除虚拟环境:rmvirtualenv 虚拟环境名
    • 虚拟环境下安装包的命令:pip install 包名
      注意:不能使用sudo pip install 包名,这个命令会把包安装到真实的主机环境上而不是安装到虚拟环境中。
    • 查看虚拟环境中安装了哪些python包:
    pip list
    pip freeze
    
    • 安装django环境:pip install django==3.0.3
      • 如果网不好,会报错:在python中安装包出现Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None))

    -- 参考链接1

    pip install django==3.0.3 -i http://pypi.douban.com/simple --trusted-host pypi.douban.com
    

    拓展:
    apt-get install 软件
    pip install python包名

    5. 项目创建

    5.1 创建Django项目

    • 命令:django-admin startproject 项目名(test1)

      注意:创建应用必须先进入虚拟环境。

    • tree可查看项目目录

    • 项目目录如下:

      • __init__.py: 说明test1是一个python包。
      • settings.py: 项目的配置文件。
      • urls.py: 进行url路由的配置。
      • wsgi.py: web服务器和Django交互的入口。
      • manage.py: 项目的管理文件。

    5.2 创建Django应用

    一个项目由很多个应用组成的,每一个应用完成一个功能模块

    • 创建应用的命令如下:python manage.py startapp 应用名(booktest)
      注意:创建应用时需要先进入项目目录。
    • 应用目录如下:
    • __init__.py: 说明目录是一个Python模块。
    • models.py: 写和数据库项目的内容, 设计模型类。
    • views.py: 接收请求,进行处理,与M和T进行交互,返回应答。定义处理函数,视图函数。
      • 定义处理函数,视图函数---相对于mini-web中的处理函数 def def add_focus(ret): # 1. 获取股票代码
    • tests.py: 写测试代码的文件。
    • admin.py: 网站后台管理相关的文件。

    5.3 应用注册

    建立应用和项目之间的联系,需要对应用进行注册,修改settings.py中的INSTALLED_APPS配置项。

    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'booktest' #加入'booktest', # 进行应用的注册
    
    ]
    

    5.4 启动项目

    • 运行开发web服务器命令:python manage.py runserver
    • 使用Django中内置的服务器:python manage.py runserver
      • 复制文件中的http://127.0.0.1:8000/到浏览器并打开(或192.168.x.xx:xxxx)
        • 如果是虚拟机中,可能出现:主机无法访问虚拟机中运行的Django项目
        • 运行Django的命令,要写成: python3 manage.py runserver 0.0.0.0:8000 ,重点就是这个0.0.0.0,这样才能让外部访问到
        • 参考链接2
      • 如果出现:Invalid HTTP_HOST header: '192.168.1.111:8000'. You may need to add '192.168.1.111' to ALLOWED_HOSTS
      • 在我们创建的项目里修改setting.py文件 ALLOWED_HOSTS = ['*'] #在这里请求的host添加了*
      • 参考链接3

    6. 模型类

    6.1 ORM

    django中内嵌了ORM框架,ORM框架可以将类和数据表进行对应起来,只需要通过类和对象就可以对数据表进行操作。

    • 在Django中主要是 设计类:模型类。
      • 在models.py文件中填写
        ORM另外一个作用:根据设计的类生成数据库中的表。

    6.2 模型类设计

    在应用models.py中设计模型类,必须继承于models.Model类。

    • 1) 设计BookInfo类。
    • 2) 设计HeroInfo类。
      Models.ForeignKey可以建立两个模型类之间一对多的关系,django在生成表的时候,就会在多端的表中创建一列作为外键,建立两个表之间一对多的关系。

    6.3 模型类生成表

      1. 生成迁移文件
      • 命令:python manage.py makemigrations
        迁移文件是根据模型类生成的。
      1. 执行迁移生成表
      • 命令:python mange.py migrate
        根据迁移文件生成表。
        生成表名的默认格式:
        应用名_模型类名小写
    • 3)安装sqliteman:sudo apt-get install sqliteman 安装失败,更换源
      • 根据迁移文件生成表,生成表名的默认格式: 应用名_模型类名小写

    6.4 通过模型类操作数据表

    • 进入项目shell的命令: python manage.py shell
      以下为在相互shell终端中演示的例子:
    • 首先导入模型类:
    > from booktest.models import BookInfo,HeroInfo
    #1)	向booktest_bookinfo表中插入一条数据。
    	b = BookInfo() #定义一个BookInfo类的对象
    	b.btitle ='天龙八部' #定义b对象的属性并赋值
    	b.bpub_date = date(1990,10,11) 
    	b.save() #才会将数据保存进数据库
    #2) 查询出booktest_bookinfo表中id为1的数据。
    	b = BookInfo.objects.get(id=1) 
    #3) 在上一步的基础上改变b对应图书的出版日期。
    	b.bpub_date = date(1989,10,21)
    	b.save() #才会更新表格中的数据
    #4) 紧接上一步,删除b对应的图书的数据。
    	b.delete() #才会删除
    #5) 向booktest_heroInfo表中插入一条数据。
    	h = HeroInfo()
    	h.hname = '郭靖'
    	h.hgender = False
    	h.hcomment = ‘降龙十八掌’
    	b2 = BookInfo.objects.get(id=2)
    	h.hbook = b2  #给关系属性赋值,英雄对象所属的图书对象
    	h.save() 
    #6) 查询图书表里面的所有内容。
    	BookInfo.objects.all()
    	HeroInfo.objects.all()
    
    

    6.4.1. models.py中:

    from django.db import models
    # 设计和表对应的类,模型类
    # Create your models here.
    
    # 一类
    # 图书类
    
    
    class BookInfo(models.Model):   # 要继承models.Model以后,才是一个模型类
        # '''图书模型类'''
        # 图书名称,Charfield说明是一个字符串,max_length指定字符串的最大长度
        btitle = models.CharField(max_length=20)
        # 出版日期,DateField说明是一个日期类型
        bpub_date = models.DateField()
    
    # 生成的db.sqlite3可以用sudo apt-get install sqliteman后,打开
    
    # django默认sqlite小型数据库,要替换成mysql
    
    
    
    # 多类
    # 英雄人物类
    # 英雄名 name
    # 性别 hgender
    # 年龄 hage
    # 备注 hcomment
    # 关系属性 hbook,建立图书类和英雄人物类之间的一对多关系
    class HeroInfo(models.Model):
    
        # '''英雄人物模型类'''
    
        hname = models.CharField(max_length=20)  # 英雄名称
    
        # 性别,BooleanField说明是bool类型,default指定默认值,False代表男
        hgender = models.BooleanField(default=False)
        # 备注
        hcomment = models.CharField(max_length=128)
        # 关系属性 hbook,建立图书类和英雄人物类之间的一对多关系
        # 关系属性对应的表的字段名格式: 关系属性名_id
        hbook = models.ForeignKey('BookInfo', on_delete=models.CASCADE,)
        # ForeignKey外键
    
    # 通过模型类操作数据表
    # 进入项目shell的命令:python manage.py shell
    #
    # 增加实例属性要和类属性名称一样
    

    6.5 关联操作

    1) 查询出id为2的图书中所有英雄人物的信息。

    b = BookInfo.objects.get(id=2)
    b.heroinfo_set.all() #查询出b图书中所有英雄人物的信息
    

    6.5.1_png

    7. 后台管理

    1) 本地化

    • 语言和时区的本地化。
    • 修改settings.py文件。
    # LANGUAGE_CODE = 'en-us'
    LANGUAGE_CODE = 'zh-hans' # 使用中文
    
    # TIME_ZONE = 'UTC'
    TIME_ZONE = 'Asia/Shanghai' # 中国时间
    

    2) 创建管理员

    • 命令:python manage.py createsuperuser
      • 执行时,可能会报错:Django项目出现: 禁止访问(403),CSRF验证失败,相应中断
      • 解决办法:在app的views.py 文件中可以添加一个 from django.template import RequestContext 然后,渲染函数render 添加即可。
        • 如: return render(request, ‘users/register.html’,context={‘form’:form})
        • 参考链接7.2

    3) 注册模型类

    在应用下的admin.py中注册模型类,告诉djang框架根据注册的模型类来生成对应表管理页面。

    from booktest.models import BookInfo, HeroInfo
    
    admin.site.register(BookInfo)
    admin.site.register(HeroInfo)
    
    • __str__:如果一个类中定义了__str__方法,那么在打印对象时,默认输出该方法的返回值
      • models.py中:重写一个__str__方法
    class BookInfo(models.Model):
        """图书模型类"""
        ...  
        def \_\_str__(self):
            # 返回英雄名
            return self.hname
    

    4) 自定义管理页面

    自定义模型管理类:模型管理类就是告诉django在生成的管理页面上显示哪些内容。

    class BookInfoAdmin(admin.ModelAdmin):
        """图书模型管理类"""
        list_display = ['id', 'btitle', 'bpub_date']
    
    class HeroInfoAdmin(admin.ModelAdmin):
        """英雄人物管理类"""
        list_display = ['id', 'hname', 'hcomment']
    
    # 注册模型类
    admin.site.register(BookInfo, BookInfoAdmin)
    admin.site.register(HeroInfo, HeroInfoAdmin)
    

    8. 视图

    在Django中,通过浏览器去请求一个页面时,使用视图函数来处理这个请求的,视图函数处理之后,要给浏览器返回页面内容。

    8.1视图函数的使用

    1) 定义视图函数

    视图函数定义在views.py中。

    • 例:
    def index(request):
        #进行处理。。。
        return HttpResponse('hello python')
    

    视图函数必须有一个参数request,进行处理之后,需要返回一个HttpResponse的类对象,hello python就是返回给浏览器显示的内容。

    2) 进行url配置---项目文件夹(test1)下的urls.py


    url配置的目的是让建立url和视图函数的对应关系。url配置项定义在urlpatterns的列表中,每一个配置项都调用url函数。
    url函数有两个参数,第一个参数是一个正则表达式,第二个是对应的处理动作。

    • 配置url时,有两种语法格式:
      • a) url(正则表达式,视图函数名)
      • b) url(正则表达式,include(应用中的urls文件))
    • 工作中在配置url时,首先在项目的urls.py文件中添加配置项,
    • 但并不写具体的url和视图函数之间的对应关系,而是写包含具体应用的urls.py文件,
    • 然后,在应用的urls.py文件中写url和视图函数的对应关系。

    8.2 url匹配的过程

    8.2_png
    在项目的/test1/urls.py文件中包含具体应用的urls.py文件,应用的/booktest/urls.py文件中写url和视图函数的对应关系。

    urlpatterns = [
        url(r'^admin/', admin.site.urls), # 配置项目
        url(r'^',include('booktest.urls')), # 包含booktest应用中urls
        # path('admin/', admin.site.urls),
    ]
    
    • 可能会报错:include()函数报错'provide the namespace argument to include() instead.' % len(arg)
      • 解决方案:url(r'^', include(('booktest.urls', 'booktest'), namespace='booktest')),
      • 参考链接8.2
    # 建议直接将项目test1/urls.py文件的内容,直接复制到应用booktest/urls.py文件中,再将不需要的地方修改掉,这样就不会错了。
    
    """test/urls.py"""
    from django.conf.urls import url, include
    from django.contrib import admin
    
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^', include(('booktest.urls', 'booktest'), namespace='booktest')),
    ]
    # ---------------------------------------------------------------------------------
    """booktest/urls.py"""
    from django.conf.urls import url
    from booktest import views
    
    
    # 创建列表urlpatterns,视图调用就是从这个列表中调用,
    # 需要通过导入from django.conf.urls import url 来调用项目的urls文件
    # 在应用的urls文件中进行url配置的时候:
    # 1.严格匹配开头和结尾
    urlpatterns = [
        # 通过url函数设置url路由配置项
        url(r'^index$', views.index),    # 写入对应的index名字,建立/index和视图index之间的关系
        # url(r'^index2', views.index2),  # 此时的输入还是“老铁,没毛病”不对,因为在上一项匹配成功后,就不再匹配下一项了
        url(r'^index2$', views.index2),   # 故,为了解决这个问题,需严格匹配开头和结尾,加上^与$
        url(r'^books$', views.show_books), # 显示图书信息,即/boos页面显示的内容
        url(r'^books/(d+)$', views.detail), # 显示英雄信息,报错,需要一个bid的位置参数,这时要将d+作为一个组()
    ]
    

    8.2.1. 当用户输入如http://127.0.0.1:8000/aindex时,去除域名和最前面的/,剩下aindex,拿aindex字符串

    8.2.2. 先到项目的urls文件中进行匹配,配置成功后,去除匹配的a字符,拿剩下的index字符串继续到项目的urls

    8.2.3. 文件中进行正则匹配,匹配成功之后执行视图函数index,index视图函数返回内容hello python给浏览器显示

    9. 模板

    模板不仅仅是一个html文件。

    9.1 模板文件的使用

    • 1 创建模板文件夹:项目test1/下面创建templates文件夹---/test1/templates/
    • 2 配置模板目录
      • settings.py文件中有TEMPLATES 选项,这个配置就是让我们去设置模板目录的。
      • 在'DIRS': []中设置模板文件的目录,设置路径,但是路径不能随便设置,而应该根据BASE_DIR来设置
      • 项目目录的绝对路径,pwd,/home/huang/bj18/test1得到的就是项目目录
      • 设置时,将BASE_DIR和模板目录进行拼接
    BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    
    TEMPLATES = [
        {
            'BACKEND': 'django.template.backends.django.DjangoTemplates',
            'DIRS': [os.path.join(BASE_DIR, 'templates')], # 设置模板文件目录,路径
            'APP_DIRS': True,
            'OPTIONS': {
                'context_processors': [
                    'django.template.context_processors.debug',
                    'django.template.context_processors.request',
                    'django.contrib.auth.context_processors.auth',
                    'django.contrib.messages.context_processors.messages',
                ],
            },
        },
    ]
    
    • 设置完模板目录后,即可使用,为了给多个应用(booktest等)使用,不混淆,会在模板文件夹(templates)下,再新建同名文件夹booktest,

    • 新建模板文件index.html,写好内容后,即可使用模板文件;

    • 在mini_frame框架中,手动打开一个文件读取出来,Django中不能这样做,使用模板文件应该遵循以下步骤:

    • 3 使用模板文件

      • 1.定义视图函数,HttpRequest
        • 在booktest下新建一个urls.py
        • 视图函数的作用是: 调用模板,处理数据并返回给浏览器。
        • 如果需要操作数据库,需要和M、T进行交互
      • 2.进行url配置,建立url地址和视图的对应关系,和Flask相似
        • 浏览器中输入http:127.0.0.1:8000/index # 用户要显示该url,需要在应用app中的urls列表中,添加该url
    from django.shortcuts import render
    from django.http import HttpResponse
    from django.template import loader, RequestContext
    from booktest.models import BookInfo, HeroInfo    # 导入模型类
    
    
    def index(request):
        ···
        return render(request, 'booktest/index.html',
                      {'content': 'hello world', 'list':list(range(1, 10))}, )
    
        urlpatterns = [
            url(r'^index$', views.index),    # 写入对应的index名字,建立/index和视图index之间的关系
    ]
    

    以下a)-c)为视图函数调用模板文件的分析过程,可省略:
    - 发现除get_template('booktest/index.html')中的'booktest/index.html'、context中的字典不同外,其余的部分都相同,
    - 故,重新定义一个函数my_render(),但此方法是多余的,因为已经导入了render,所以可以直接使用
    ```
    def my_render(request, template_path, context_dict):
        """使用模板文件"""
        # 直接将index中的模板文件拿过来使用
        # 1.加载模板文件
        temp = loader.get_template(template_path)  # 写上目录,该目录是相对templetes的目录---改为template_path
        # 2.定义模板文件上下文:给模板文件传递数据,request,和要传递的数据,通过{}的键值对来传减去
        # 导入from django.template import loader, RequestContext
        # context = RequestContext(request, {''})   # Django1.11以后,就是直接传入{}即可,不再传入RequestContext(request, {''})---{}字典也改为通过context_dict来改变
        # context = {}
        context = context_dict
        # 3.模板渲染(目的是把使用的变量,还有一些语句给替换掉):产生标准的html内容,temp中有一个render方法,将context放进去
        res_html = temp.render(context)
        # 4.返回给浏览器
        return HttpResponse(res_html)
    ```
        - a)加载模板文件----views.py中,使用模板文件 # 1.加载模板文件
            - 导入包 from django.template import loader
            - temp = loader.get_template('booktest/index.html')  # 写上目录,该目录是相对templetes的目录
        - b) 定义目标上下文---给模板文件传递定义的变量的值
            - 给**模板文件传递数据**:request和要传递的数据,通过{}的键值对来传进去
                - 导入from django.template import loader, RequestContext
                - context = RequestContext(request, {''})   # Django1.11以后,就是直接传入{}即可,不再传入RequestContext(request, {''})
                - # context = {}
        - c) 模板渲染(目的是把使用的变量,还有一些语句给替换掉):产生标准的html内容,temp中有一个render方法,将context放进去
            - res_html = temp.render(context)
        - d) 返回给浏览器
            - return HttpResponse(res_html)
    

    9.2 给模板文件传递数据

    • 模板变量使用:{{ 模板变量名 }}
    • 模板代码段:{%代码段%}
    • for循环:
    {% for i in list %}
    	list不为空时执行的逻辑
    {% empty %}
    	list为空时执行的逻辑
    {% endfor %}
    
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>模板文件</title>
        <style type="text/css">
        </style>
    </head>
    <body>
    <h1>这是一个模板文件</h1>
    使用模板变量:<br/>
    {{ content }}<br/>
    使用列表:<br/>
    {{ list }}<br/> # 这是直接显示列表的内容,py中还可以遍历出列表中的每一个文件
    for循环:<br/>
    <ul>
        {% for i in list %}
            <li>{{ i }}</li>
        {% endfor %}
    </ul>
    </body>
    </html>
    

    9.3:小结:

    • 我们需要做的事情:
      • 1)定义视图函数
        • 视图函数定义在views.py中。
      • 2)进行url配置,项目视图+应用视图,两个。
        • """test/urls.py"""
        • """booktest/urls.py"""

    10. 案例完成

    编码之前的准备工作:

    • 1 设计出访问页面的url和对应的视图函数的名字,确定视图函数的功能。

      • def show_books()、detail()
    • 2 设计模板文件的名字。

      • area.html、index.html

      以下为案例中的简单设计过程:

    • 1 完成图书信息的展示:

      • 1.1 设计url,通过浏览器访问 http://127.0.0.1:8000/books 时显示图书信息页面。
        # /test1/urls.py:
        urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^', include(('booktest.urls', 'booktest'), namespace='booktest')),
        ]
        
        #/booktest/urls.py:
        urlpatterns = [
            # 通过url函数设置url路由配置项
            url(r'^index$', views.index),
            url(r'^books$', views.show_books), # 显示图书信息,即/books页面显示的内容
            url(r'^books/(d+)$', views.detail), # 显示英雄信息,报错,需要一个bid的位置参数,这时要将d+作为一个组()
        ]
        
    • 1.2 设计url对应的视图函数show_books。

      • 查询出所有图书的信息,将这些信息传递给模板文件。
        # views.py:
        import sys
        from django.shortcuts import render
        from django.http import HttpResponse
        from django.template import loader,
        from booktest.models import BookInfo, HeroInfo    # 导入模型类
        
        
        def show_books(request):
            """显示图书的信息"""
            # 1. 通过M查找图书表中的数据
            books = BookInfo.objects.all()
            # 2. 使用模板
            return render(request, 'booktest/show_books.html', {'books': books})
        
    • 1.3 编写模板文件show_books.html。

      • 遍历显示出每一本图书的信息。
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>显示图书信息</title>
        <style type="text/css">
        </style>
    </head>
    <body>
    图书信息如下:
        {% for book in books %}
            <li><a href="/books/{{ book.id }}">{{ book.btitle}}</a></li>
        {% endfor %}
    </body>
    </html>
    
    • 2 完成点击某本图书时,显示出图书里所有英雄信息的页面。
      • 2.1 设计url,通过访问http://127.0.0.1:8000/books/数字时显示对应的英雄信息页面。
        • 这里数字指点击的图书的id。
          url(r'^books/(d+)$', views.detail), # 显示英雄信息,报错,需要一个bid的位置参数,这时要将d+作为一个组()
          
      • 2.2 设计对应的视图函数detail。
        • 接收图书的id,根据id查询出相应的图书信息,然后查询出图书中的所有英雄信息。
          def detail(request, bid):
              '''查询图书关联英雄信息'''
              # 1. 根据bid查询图书信息
              book = BookInfo.objects.get(id=bid)
              # 2. 查询和book关联的信息---要分析1对多(由1查多b.heroinfo_set.all())还是多对1(h.hbook)
              # HeroInfo.objects.fliter(hbook__id=1)
              heros = book.heroinfo_set.all()
              # 需要显示图书的名字,和关联的英雄名字和备注
              # 3. 使用模板detail,创建templates/bootest/detail.html
              return render(request, 'booktest/detail.html', {'book': book, 'heros': heros})  # 注意,此处是heros,不是hero,不然图书信息就无法显示
              # 去应用booktest/urls中设置地址。
          
      • 2.3 编写模板文件detail.html:
      <!DOCTYPE html>
      <html lang="en">
      <head>
          <meta charset="UTF-8">
          <title>显示图书关联的英雄信息</title>
          <style type="text/css">    
          </style>
      </head>
      <body>
      <h1>{{ book.btitle }}</h1>
      英雄信息如下:<br/>
      <ul>
          {% for hero in heros %}
              <li>{{ hero.hname }}--{{ hero.hcomment }}</li>
          {% empty %}
              <li>没有英雄信息</li>
          {% endfor %}
      </ul>
      
      </body>
      </html>
      
  • 相关阅读:
    【php】错误日志处理
    【php】正则表达式
    【php】字符串
    【PHP】数组
    【PHP】函数
    【PHP】流程控制
    【PHP】PHP运算符
    【PHP】PHP基本语法
    【前端】CSS总结
    SVN与Apache整合
  • 原文地址:https://www.cnblogs.com/wangxue533/p/12369616.html
Copyright © 2020-2023  润新知