• Django-2.1基础操作


     创建项目


    安装django

    pip3 install django
    #查看django版本
    django-admin --version
    python -m django --version
    2.1.2

    1,创建一个项目(project)

    django-admin startproject mysite  # 创建project
    # cd mysite #创建完成后,生成的project目录
    # tree
    |-- manage.py
    |-- mysite
    | |-- __init__.py
    | |-- settings.py
    | |-- urls.py
    | `-- wsgi.py

    # wsgi.py (python web server gateway interface python)服务器网关接口,python应用与web服务器之间的接口
    # urls.py url配置文件,django项目中的所有地址都需要配置其url
    # settings.py 项目总配置文件,包含了数据库,web应用,时间等各种配置

    BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) #django根目录
    SECRET_KEY = ')(^))edmyp7-eork0c%+=q(6ll18(7lce$i)ynsoo2h5m+7v27'  #安全码
    DEBUG=True  #(默认的,访问url出错会显示调试的页面,生产环境应该改为False)
    ALLOWED_HOSTS = []  # 白名单, 如果DEBUG=False,那么一定要设置此项
    INSTALLED_APPS = [   
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        "app01",              #把自己创建的应用加入进来才能被django识别
        "app02"
    ]
    ROOT_URLCONF = 'project_test.urls'   #全局url
    DATABASES = {         # 数据库配置
        'default': { 
            'ENGINE': 'django.db.backends.sqlite3',          #数据库引擎
            'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),    #数据库名
          #  "ENGINE": 'django.db.backends.mysql',  #使用mysql数据库
          #  'NAME': 'mydb',       #数据库名
          #  'HOST': 'localhost',   #ip
          #  'PORT': '3306',        #端口,注意是字符串
          #  'USER': 'root',      #用户名
          #  'PASSWORD': 'password'   #密码
        }
    }
    # LANGUAGE_CODE = 'en-us'
    LANGUAGE_CODE = 'zh_Hans'  #可以改成中文
    TIME_ZONE = 'UTC'  #时区,生产环境改成Asia
    STATIC_URL = '/static/'  #static 是静态文件目录,比如 js,css等文件
    settings.py配置文件

    2,创建应用(app)

    # python manage.py startapp app01 创建app01,生成了app01目录
    |-- app01
    | |-- admin.py   #当前应用的后台管理系统配置
    | |-- apps.py   
    | |-- __init__.py
    | |-- migrations   #数据移植(迁移)模块,下面的文件是django自动生成
    | | `-- __init__.py
    | |-- models.py   #数据模块,使用orm框架
    | |-- tests.py   #自动化测试模块
    | `-- views.py   #视图模块,执行响应的代码,处理代码逻辑
    |-- manage.py
    |-- mysite
    | |-- __init__.py
    | |-- settings.py
    | |-- urls.py
    | `-- wsgi.py
    # python manage.py startapp app02  可以创建多个应用

    3,运行django程序的命令

    # cd mysite #进入project 
    # python manage.py runserver 127.0.0.1:8000 #运行命令

    访问http://127.0.0.1:8000/ 可以看到django已经安装成功,只是此时并未配置任何url

    删除一个app

    • 首先删除models.py。# python  manage.py migrate app_name zero 删除models.py中的数据模型。
    • 删除app目录。在settings.py的INSTALLED_APPS中移除该app。

    视图与路由  


    urls 控制器    根据url匹配相应的视图函数

    views 视图    逻辑处理,决定给前端展示什么数据,调用models数据库里的数据,把要展示的数据返回给模板

    创建project 和app之后, # vim mysite/mysite/settings.py  

    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'app01',   #加入这一行
    ]

    # 将新建的app加入到settings的INSTALLED_APPS中,django 就能自动找到app中的模板文件(app/templates/文件)和静态文件(app/static/文件)

    定义视图view   vim app01/views.py

    from django.http import HttpResponse
    
    def test(request):
        return HttpResponse("hello django,this is a test message")

    定义url   vim mysite/urls.py

    from django.contrib import admin
    from django.urls import path
    from app01 import views   #导入views
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('test/', views.test)    # 加入这一行
    ]

    运行python,访问http://127.0.0.1:8000/test/ 可以看到

    path方法 (不支持正则,正则请用re_path)

    默认情况下,以下路径转换器可用:

    • str -  匹配除路径分隔符'/'之外的任何非空字符串。如果转换器未包含在表达式中,则这是默认值。
    • path - 匹配任何非空字符串,包括路径分隔符 '/'。这使您可以匹配完整的URL路径,而不仅仅是URL路径的一部分str
    • int  - 匹配零或任何正整数。返回一个int
    • slug - 匹配由ASCII字母或数字组成的任何slug字符串,以及连字符和下划线字符。例如,building-your-1st-django-site
    • uuid  - 匹配格式化的UUID。要防止多个URL映射到同一页面,必须包含短划线并且字母必须为小写。例如,075194d3-6885-417e-a8a8-6c931e272f00

    示例:

    # urls.py
    from app01 import views
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('add/<int:num1>/<int:num2>',views.add),
        path('add/<path:str2>/<path:str1>',views.addstr),
    ]
    # views.py
    def add(request,num1,num2):
        addnum = num1 + num2
        return HttpResponse(addnum)
    def addstr(request,str1,str2):
        strs = str1 + str2
        return HttpResponse(strs)
    访问 http://127.0.0.1:8000/add/2/3 
    得到 5
    访问 http://127.0.0.1:8000/addstr/a/b 
    得到 ba

    也可以注册自定义路径转换器

    1,先定义一个类 。

    2,用to_python(self, value) 方法把匹配的字符串转换成要传递到视图函数的类型

    3,用to_url(self, value) 方法把python数据类型转换成url要使用的字符串。

    # vim converters 
    class FourDigitYearConverter:
        regex = '[0-9]{4}'
        def to_python(self, value):
            return int(value)
        def to_url(self, value):
            return '%04d' % value
    
    # vim urls.py
    from django.contrib import admin
    from django.urls import path,register_converter
    from app01 import views
    from . import converters
    register_converter(converters.FourDigitYearConverter, 'yyyy')   #注册一个yyyy转换器
    urlpatterns = [
        path('mydefine/<yyyy:strs>/',views.years)   #使用yyyy转换器匹配
    ]
    # 使用register_converter()命令在URLconf中注册自定义转换器类
    
    # vim views.py
    def years(request,strs):
        return HttpResponse(strs)    
    
    访问http://127.0.0.1:8000/mydefine/2018/ 
    得到 2018
    示例

    re_path() 方法

    如果path的转换器语法不足以定义url模式,可以使用正则表达式来匹配。

    # urls.py
    from django.contrib import admin
    from app01 import views
    from django.urls import re_path   #导入模块
    urlpatterns = [
        path('admin/', admin.site.urls),
        re_path(r'^test/',views.test),
        re_path(r'^datetime/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>d+)',views.date)
    ]                          #指定参数 year month day,views里面的参数也必须是这个名字不然会出错
    # views.py def test(request): now = datetime.datetime.now() html = "<html><body>now: %s.</body></html>"%now return HttpResponse(html) def date(request,year,month,day): strs = year+month+day return HttpResponse(strs) 访问 http://127.0.0.1:8000/test/ 返回now: 2018-12-11 10:50:58.328433. 访问 http://127.0.0.1:8000/datetime/2018/12/11 返回20181211

    使用include 解耦

    1,一级url 。在项目的根urls.py中引入 path('app/',include('app.urls.py'))  
    2,二级url。 在app目录中创建urls.py文件,格式与urls.py相同 

    from django.contrib import admin
    from django.urls import path
    from django.conf.urls import include
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('app01/', include('app01.urls')),
    ]
    mysite.urls.py
    from django.conf.urls import re_path
    from django.urls import path
    from . import views
    
    urlpatterns = [
        re_path('^index/$', views.index),
    ]
    app01.urls.py
    from django.shortcuts import render
    from django.http import HttpResponse
    def index(request):
        return HttpResponse('ok')
    app01.views.py

    这里访问 http://127.0.0.1:8000/app01/index/  返回 ok

    Template 模板


    存放html文件,使用django模板语言(django template language,DTL)

    前面都是简单的用 django.http.HttpResponse 来把内容显示到网页上,这里将介绍使用渲染模板来显示内容。

    步骤:

      1, 在app的根目录下创建名为templates的目录
      2, 在该目录下创建html文件
      3, 在views.py 中返回render()

    简单的栗子:

    在app01下面创建一个templates文件夹,在templates中创建index.html文件

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <h1>hello,app01</h1>
    </body>
    </html>
    index.html

    在app01/views.py中

    from django.shortcuts import render
    from django.http import HttpResponse
    def index(request):
        return  render(request,'index.html')  #把index.html文件显示在页面上
    views.py

    urls.py 配置省略

    访问 http://127.0.0.1:8000/app01/index/  返回 hello,app01

    注意:创建多个app时,应该在app的templates目录下创建以app名为名称的目录,将html文件放入新创建的目录下

    因为Django查找template是按照INSTALLED_APPS中添加顺序查找,不同app下Templates目录中的同名.html文件会造成冲突

    render渲染

    render()函数中支持dict类型的参数,该字典是后台传递到模板的参数,字典的键即为传入的参数
    在模板中使用{{键名}}来直接使用

    变量使用 {{ }}   条件判断和循环使用{% %}

    命令行模式:  python3 manage.py shell 

    示例1:使用变量

    vim app01/views.py

    from django.shortcuts import renderdef index(request):
        words = "this is app01 test"
        return  render(request,'app01/index.html',{ "strings": words})

    vim app01/templates/app01/index.html

    {{ strings }}

     访问http://127.0.0.1:8000/app01/index/  返回 this is app01 test

    示例二:字典

    vim views.py

    def index(request):
        dic = {'k1':'v1','k2':'v2'}
        return  render(request,'app01/index.html',{"test_dict":dic})

    vim index.html

    {{ test_dict.k1 }}   #注意这里字典取值不是用dict[k1] 而是.  列表索引也是一样的 l.0

     访问http://127.0.0.1:8000/app01/index/  返回v1

    还可以使用字典操作:

    {% for key,value in test_dict.items %}
        {{ key }} : {{ value }}
    {% endfor %}

    示例二:类的实例也可以被渲染

     vim views.py

    def index(request):
        class Myclass(object):
            def __init__(self,name,age):
                self.name = name
                self.age = age
        return render(request,"app01/index.html",{"myclass":Myclass("lily",23)})

    vim index.html

    name:{{ myclass.name }} age:{{ myclass.age }}

    访问http://127.0.0.1:8000/app01/index/    返回 name:lily age:23

    示例三:循环 for

    views.py

    from django.shortcuts import renderdef index(request):
        test_list = ['aaa','bbb','ccc']
        return  render(request,'app01/index.html',{"t_list":test_list})

    index.html

    {% for item in t_list %}
    {{ item }},
    {% endfor %}

    访问 http://127.0.0.1:8000/app01/index/  返回 aaa, bbb, ccc,

    模板中的逻辑操作符:

    ==, !=, >=, <=, >, < 

    and, or, not, in, not in

    view.py

    def index(request):
        return  render(request,'app01/index.html',{"num":3})

    index.html

    {% if num > 10 %}
    大于10
    {% elif num < 10 %}
    小于10
    {% else %}
    等于10
    {% endif %}

    访问http://127.0.0.1:8000/app01/index/   返回 小于10

    include  引用其他文件的内容

    urls.py

    urlpatterns = [
        re_path('^p1/$', views.page1),
        re_path('^p2/$', views.page2),
    ]

    views.py

    def page1(request):
        return render(request,"app01/page1.html")
    def page2(request):
        return render(request, "app01/page2.html")

    templates/app01/page1.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>p1</title>
    </head>
    <body>
    <h1>Welcome to page1</h1>
    </body>
    <footer>
        page1 end----
    </footer>
    </html>
    templates/app01/page1.html

    templates/app02/page2.html

    {% include 'app01/page1.html' %}   #引入page1.html的内容
    <h1>this is page2</h1>

     

    extends  继承和扩展

     templates/app01/page1.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>p1</title>
    </head>
    <body>
    {% block page1_content %}   #其他子页面如果继承了此页面,那么通过这个block重写这一块内容
    <h1>Welcome to page1</h1>
    {% endblock %}          #结束位置
    </body>
    <footer>
        page1 end----
    </footer>
    </html>

    templates/app01/page2.html

    {% extends 'app01/page1.html' %}   #继承page1.html
    {% block page1_content %}     #要重写的部分
    <h1>this is page2</h1>
    {% endblock %}

    models 模型


    通常一个model类对应数据库的一张数据表
    Django中models以类的形式表现,它包含了一些基本字段以及数据的一些行为

    orm框架    orm(obje relation mapping)对象关系映射
    实现了对象和数据库之间的映射,隐藏数据访问的细节,不需要编写原生的sql语句

    类 <--->数据表
    属性 <--->字段
    对象 <--->记录

     使用models的一个小栗子:

    1,在app根目录models.py中创建一个类,继承models.Models,该类即是一张数据表,在类中创建字段

    vim models.py

    from django.db import models
    class Article(models.Model):
        title = models.CharField(max_length=32,default='title')
        content = models.TextField(null=True)

    2,生成数据表

        1.  python manage.py makemigrations [appname]   如果不指定appname则所有都执行

       执行之后会自动在app01/migrations下面生成了0001_initial.py

        2.  python manage.py migrate   

       执行之后,数据库会生成在项目根目录下db.sqlite3

        3. 可以查看sql语句:  > python manage.py sqlmigrate app01 0001

    >  python manage.py sqlmigrate app01 0001
    BEGIN;
    --
    -- Create model Article
    --
    CREATE TABLE "myblog_article" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "title" varchar(32) NOT NULL, "content" text NULL)
    ;
    COMMIT;

     数据库生成在项目根目录下的db.sqlite3,可以使用软件打开,会看到article表已经生成

    3, 插入几条数据 id:1  title:title  content:test app01

    4,后台呈现数据

    修改views.py

    from django.shortcuts import render
    from django.http import HttpResponse
    from . import models
    def index(request):
        article_obj = models.Article.objects.get(id=1)  #获取Article表中id=1的记录 
        return  render(request,'app01/index.html',{'article':article_obj})

    5,  前端展示

    <h1>{{ article.title }}</h1>
    <h3>{{ article.content }}</h3>

    访问http://127.0.0.1:8000/app01/index/  得到:title: title content: test app01 

    Admin  后台管理


     Admin是django自带的一个功能强大的后台管理系统,被授权的用户可以直接在admin中管理数据库

    1, 访问127.0.0.1:8000/admin可以看到django自带的后台界面。需要设置用户名密码登录

      2,创建用户名密码 

    >python manage.py createsuperuser    #创建后台用户名密码

       使用用户名密码登录后台,此时只能看到django后台默认的界面。

    3,配置admin.py 

    from django.contrib import admin
    # Register your models here.
    from .models import Articles
    admin.site.register(Article)

    4,再次访问后台,可以看到数据库。通过后台可以直接对数据库数据进行增删改操作

    5,添加两条数据可以看到:

     

    为了更加直观的看到添加的数据,可以在models.pyl里面的类中加上一个方法:

    def __str__(self):
    return self.title
    再次查看,可以看到文章标题

    6,如果要自定义显示的字段,可以修改admin.py

    from django.contrib import admin
    from .models import Article
    class Article_Moreinfo(admin.ModelAdmin):   #自定义一个类
        list_display = ('title','content')   #list_display配置要显示的字段
    admin.site.register(Article,Article_Moreinfo) 

  • 相关阅读:
    Python 高级编程系列__03:python 中常见的内置类型
    Python 高级编程系列__02:type、object、class 的关系
    Python 高级编程系列__01:一切皆对象
    Mac 修改默认python的版本
    swap指令实现互斥
    什么是进程同步?wait( )是如何实现进程同步的?
    可执行文件加载时进行了哪些处理?
    C++不允许使用不完整的类型说明
    error LNK2019: 无法解析的外部符号
    抽屉原理——放苹果
  • 原文地址:https://www.cnblogs.com/xiaobaozi-95/p/10095529.html
Copyright © 2020-2023  润新知