zoukankan      html  css  js  c++  java
  • django 快速入门

    转载https://www.cnblogs.com/changqing8023/p/10273210.html

    Django是Python语言编写的一个全栈式Web框架,可以帮助我们快速编写一个具有数据库功能、增删查改、后台管理等功能的网站。假如你只需要一些很简单的功能,使用flask可能是个更好的选择。但是如果你想快速实现一个XX管理系统,那么用Django绝对是个好办法。本文参考了Django官方文档的Tutorials。另外我这里用的终端是Powershell,如果有些命令不能运行,去掉前面的.

    快速开始

    安装Django

    首先安装Django包,现在Django已经到了2.0版本,如果还在使用1.11请尽快升级。旧版本以后只修复bug,不会添加新功能。

    pip install django

    创建项目

    Django安装好之后,会附带一个命令行工具django-admin,可以帮助我们管理Django项目。我们可以使用下面的命令创建一个新的Django项目模板。这样会创建django_sample文件夹,项目文件就在其中。另外需要注意项目文件夹最好是个性化一点的,不要和django、sys这样的第三方库或者python系统库重名。

    django-admin startproject hello_django

    创建好项目之后,我们进入项目文件夹中。用下面的命令就可以运行Django项目了。默认情况下,我们可以通过http://127.0.0.1:8000/来访问正在运行的项目。由于没有任何页面,所以会显示这么一个调试窗口。

    python manage.py runserver

    运行成功

    创建app

    在Django项目中,app表示更小的一个功能单位,比方说在一个博客管理系统中,对博客的增删查改等功能就应该聚合在一个app中。进入项目目录中,用startapp命令创建app。

    cd .hello_django
    django-admin startapp hello

    这时候项目目录结构应该类似这样。

    目录结构

    为了让django包含创建的app,我们还需要激活app。打开配置文件,找到INSTALLED_APPS,然后把我们创建的app配置添加进去,这样django才能使用我们的app。

    INSTALLED_APPS = [
        'hello.apps.HelloConfig',
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
    ]

    模型层

    设置数据库

    打开配置文件settings.py,找到数据库一行,可以看到如下的配置。

    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.sqlite3',
            'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
        }
    }

    如果我们这时候使用python .manage.py migrate命令生成数据库表,就会在项目中出现一个db.sqlite3文件,这就是默认的数据库文件,使用IDEA右键点击并选择As DataSource就可以将其作为数据库打开。然后我们会看到生成了10多个数据库表,这是Django程序存储数据生成的表。

    django系统表

    除了sqlite数据库,django还支持POstgreSQL、MySQL、Oracle这几个数据库。如果添加第三方后端支持,还可以使用SQL Server、IBM DB2等数据库。例如我现在准备使用PostgreSQL数据库,就修改为下面的配置。这时候NAME属性的意义就是数据库的名字。另外必须确保数据库事先存在,django可以自动创建表,但是不能自动创建数据库。

    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.postgresql',
            'NAME': 'test',
            'USER': 'postgres',
            'PASSWORD': '12345678',
            'HOST': '127.0.0.1',
            'PORT': '5432',
        }
    }

    创建模型

    django支持ORM模型,也就是说我们可以不使用SQL语句就对数据进行增删查改。我们要做的就是在模型中指定和数据库的关系。

    打开hello app中的models.py文件,然后添加下面两个模型。这两个模型是宠物和主人的关系。如果使用过其他ORM框架比如Hibernate之类的话,对这种结构应该非常熟悉。我们在定义模型的时候指定每一个字段的名字、长度、是否唯一等信息。值得注意的是,如果需要的值只可能是几个固定值,可以定义一个元组(该元组有一对值构成,第一个值是实际存在数据库中的值,第二个是给人类显示的友好可读值),然后传入choices参数。models.ForeignKey用来指定外键约束,还有一些其他的对应关系例如多对多、一对一等就不介绍了。

    from django.db import models
    
    class Owner(models.Model):
        GENDER = (
            ('M', 'MALE'),
            ('F', 'FEMALE')
        )
        id = models.AutoField(primary_key=True)
        name = models.CharField(max_length=30, unique=True)
        gender = models.CharField(max_length=1, choices=GENDER)
        birthday = models.DateField()
    
    
    class Pet(models.Model):
        TYPE = (
            ('C', 'Cat'),
            ('D', 'Dog')
        )
        id = models.AutoField(primary_key=True)
        owner = models.ForeignKey(Owner, on_delete=models.CASCADE)
        name = models.CharField(max_length=50)
        type = models.CharField(max_length=1, choices=TYPE)
    

    生成并应用迁移文件

    上面我们创建了两个模型,实际上,只要我们对模型进行了更改,就应该使用下面的命令生成这些更改。

    python manage.py makemigrations hello
    Migrations for 'hello':
      hellomigrations0001_initial.py
        - Create model Owner
        - Create model Pet

    并且在migration文件夹中生成了对应的迁移文件。

    如果想知道迁移文件会具体生成什么样的SQL语句,可以调用下面的命令。这里的序号是迁移序号,每次对模型进行更改都会生成一个新的迁移文件,想查看哪个文件生成的SQL语句,就指定哪个序号。

    python manage.py sqlmigrate hello 0001

    结果应该类似下面这样。

    BEGIN;
    --
    -- Create model Owner
    --
    CREATE TABLE "hello_owner" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varchar(30) NOT NULL UNIQUE, "gender" varchar(1) NOT NULL, "birthday" date NOT NULL);
    --
    -- Create model Pet
    --
    CREATE TABLE "hello_pet" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varchar(50) NOT NULL, "type" varchar(1) NOT NULL, "owner_id" integer NOT NULL REFERENCES "hello_owner" ("id") DEFERRABLE INITIALLY DEFERRED);
    CREATE INDEX "hello_pet_owner_id_a7d7b3df" ON "hello_pet" ("owner_id");
    COMMIT;

    当然这只是生成了迁移文件,并没有真正应用到数据库中。如果要引用到数据库,再次使用migrate命令即可。这时候再次查看数据库,就会发现多了hello_owner和hello_pet两个表,正好对应我们的两个模型。

    python manage.py migrate

    数据操作

    用下面的命令打开django Shell。

    python manage.py shell

    如果不想使用命令,也可以设置DJANGO_SETTINGS_MODULE环境变量的项目的settings.py文件,然后在python解释器中设置django shell。

    >>> import django
    >>> django.setup()

    不管是用哪种方法,都可以打开shell,在这里面就可以使用API操作数据了。首先引入我们的模型。

    In [1]: from hello.models import Owner, Pet

    增加一些数据。

    In [4]: o1=Owner(name='zhang3',birthday='1992-5-7',gender='M')
    In [5]: o1.save()
    In [6]: o2=Owner(name='limei',birthday='1996-6-8',gender='F')
    In [7]: o2.save()
    In [8]: p1=Pet(owner=o1,name='lele',type='D')
    In [9]: p1.save()

    下面是一些查询例子,get函数查询单个模型,filter函数查询多个模型,all函数查询所有模型。

    In [7]: Pet.objects.all()
    In [8]: Pet.objects.get(id=1)
    In [11]: Owner.objects.get(name='zhang3')
    In [14]: Owner.objects.filter(gender='M')
    In [18]: Owner.objects.count()

    上面的只能执行精确查找某个字段,如果需要更复杂的可以使用双下划綫加查询谓词的形式。详细文档参考https://docs.djangoproject.com/en/2.0/topics/db/queries/#field-lookups-intro

    In [20]: Owner.objects.filter(name__startswith='z')
    In [22]: Owner.objects.filter(birthday__year__lte='1994')
    In [30]: Owner.objects.filter(name__contains='5')

    删除某个对象。

    In [31]: p2.delete()

    为了调试更方便,我们还可以在这两个模型上添加str函数。这样调试的时候就更加易读了。

    class Owner(models.Model):
    
        def __str__(self):
            return f'Owner(id:{self.id}, name:{self.name}, gender:{self.gender}, birthday:{self.birthday}'
    
    
    class Pet(models.Model):
    
        def __str__(self):
            return f'Pet(id:{self.id}, name:{self.name}, type:{self.type}'

    Django Admin

    Django Admin可以帮助我们快速管理后台数据。首先需要创建一个管理员账户。

    python manage.py createsuperuser

    创建完成后,通过http://127.0.0.1:8000/admin/访问管理员界面并输入刚才设置的管理员和密码,会看到如下的界面。

    管理员界面

    这里目前什么都没有,我们需要将模型注册到Admin中。打开admin.py文件,输入下面的内容。

    from django.contrib import admin
    
    # Register your models here.
    from .models import Owner, Pet
    
    admin.site.register(Owner)
    admin.site.register(Pet)
    

    这样一来,就可以在管理员界面中管理模型了。
    管理模型

    页面和视图

    路由

    首先在app的views.py中添加一个新的视图。不过按照Spring MVC的分层,我觉得这里的这些视图叫控制器似乎更合理一些,不过既然这个文件都叫做view,那么我也叫它视图吧。

    from django.http import HttpResponse
    
    def index(request):
        return HttpResponse('hello')
    

    然后在app中创建一个urls.py文件,写入以下内容。

    from django.urls import path
    from . import views
    
    urlpatterns = [
        path('', views.index, name='index'),
    ]

    然后在项目的urls.py文件中添加app中设置的路径,除了admin页面的路径之外,其他路径都应该使用include函数引入。

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

    然后访问http://127.0.0.1:8000/hello/,应该就可以看到显示的字符串了。

    路径参数

    如果路由是带路径参数的,那么使用<类型:变量名>语法。

    urlpatterns = [
        path('', views.index, name='index'),
        path('hello/<str:name>', views.hello, name='hello')
    ]

    对应的参数作为视图函数的第二个参数。

    def hello(request, name):
        return HttpResponse(f'hello, {name}')

    这样,访问http://127.0.0.1:8000/hello/hello/yitian就可以看到对应的输出了。

    使用模板

    在app中创建templates/hello文件夹,然后在其中创建index.html文件,文件内容如下。

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <title>主页</title>
    </head>
    <body>
    <h1>Hello,{{ name }}</h1>
    </body>
    </html>

    然后修改view.py文件,将hello视图修改为下面的样子。再次访问就可以看到这次成功的返回了网页。

    from django.http import HttpResponse
    from django.template import loader
    
    def hello(request, name):
        template = loader.get_template('hello/index.html')
        context = {'name': name}
        return HttpResponse(template.render(context, request))

    django还提供了快捷render函数可以简化这个返回模板的常见过程。

    from django.http import HttpResponse
    from django.shortcuts import render
    
    def hello(request, name):
        context = {'name': name}
        return render(request, 'hello/index.html', context)

    有些同学可能有疑问,为什么模板文件夹中还要在创建一个hello子文件夹呢?这是由于django的文件搜索机制所导致的。当搜索模板文件的时候django会从所有app的templates文件夹中搜索,但是并不会区分它们,所以如果在多个app中有相同的文件名,django会使用找到的第一个。因此为了区分它们我们只能自己多创建一层文件夹用于区分。

    和flask一样,django默认使用Jinja2模板,关于jinja2的语法请查阅相关文档,这里就不在详细说明了。

    页面中使用URL

    当我们在页面中需要使用路径的时候,不要硬编码路径,最好使用url标签。例如下面这样的。

    <a href="{% url 'hello' '张三' %}">你好,张三</a>

    这里url标签中指定的名称是urls.py文件中路径的name参数。

    path('hello/<str:name>', views.hello, name='hello')

    当项目中存在多个app的时候,需要使用命名空间来区分。做法很简单,在urls.py文件中添加app_name属性。

    app_name = 'hello'
    urlpatterns = [
        path('', views.index, name='index'),
        path('hello/<str:name>', views.hello, name='hello')
    ]

    然后在标签上添加用冒号分隔开的命名空间名称即可。

    <a href="{% url 'hello:hello' '张三' %}">你好,张三</a>

    获取表单参数

    在页面中添加如下一个表单。{% csrf_token %}标签是django内建的功能,可以帮助我们防止csrf攻击。

    <form action="{% url 'hello:form' %}" method="post">
        {% csrf_token %}
        <label for="name">name</label>
        <input type="text" name="name" id="name">
        <br/>
        <label for="male">male</label>
        <input type="radio" name="gender" value="male" id="male">
        <label for="female">female</label>
        <input type="radio" name="gender" value="female" id="female">
        <br>
        <label for="age">age</label>
        <input type="text" name="age" id="age">
        <br>
        <input type="submit" value="submit">
    </form>

    然后添加下面一条路径。

    path('form', views.get_form, name='form')

    最后添加处理函数,这个处理函数很简单,仅仅返回结果文本。需要获取参数的时候,直接用request.POST即可,它是一个类似字典的对象,我们可以通过键来访问对应参数的值。

    def get_form(request):
        form = request.POST
        return HttpResponse(f"name:{form['name']}, gender:{form['gender']}, age:{form['age']}")

    静态文件

    app内静态文件

    对于样式表等静态文件,如果是位于app内的,不需要额外设置。只要在app内创建static文件夹并将静态文件放入即可。之后在页面中引用的时候添加下面的标签即可。注意在使用static标签之前,需要用{% load static %}加载它。

        {% load static %}
        <link rel="stylesheet" href="{% static 'site.css' %}">

    文件结构类似下图。
    静态文件结构

    需要注意的是,由于前面介绍的django文件搜索机制,在静态文件夹中,我们最好在指定一级和app同名的文件夹用来区分不同app间的静态文件。

    项目公用静态文件

    有些静态文件可能是多个app公用的,这时候需要进行一点额外设置。首先在和app同级的目录创建static文件夹并将静态文件放入。然后在配置文件中添加额外的搜索路径配置。

    STATICFILES_DIRS = [
        os.path.join(BASE_DIR, "static"),
    ]

    还是由于django文件搜索机制,我们最好在静态目录中添加一个public子文件夹和其他静态文件区分。

    测试

    django支持自动化测试,可以帮助我们快速查找bug。测试文件应该写到tests.py文件中。下面是一个简单的例子。

    from django.test import TestCase
    
    
    class SampleTest(TestCase):
        def test_true(self):
            self.assertTrue(True, 'is true')

    TestCase基类含有各种断言方法,可以帮我们进行判断,这里就不列举了。

    要运行测试的话,使用下面的命令。可以看到django还会自动创建和删除测试数据库,非常方便。

    PS D:kangPycharmProjectspython-studyhello_django> python .manage.py test hello
    Creating test database for alias 'default'...
    System check identified no issues (0 silenced).
    .

    Ran 1 test in 0.015s

    OK
    Destroying test database for alias 'default'...

    以上就是一点对于django框架的介绍。希望大家在看完之后可以对django框架有一些基本了解。本来我是准备照着官方文档的教程来写的,但是写了一半感觉教程内容太多,没办法放到一篇文章中。所以就写成了这么一个虎头蛇尾的文章。之后有时间我会慢慢写文章,仔细介绍django的各个方面的内容。

    另外安利一个学习教程:无敌django+xadmin 打造上线平台(视频+源码)

    分享一个资源网站平台:     点击进入

  • 相关阅读:
    HDU4507 吉哥系列故事――恨7不成妻(数位dp)
    UCF Local Programming Contest 2017 G题(dp)
    ICPC Latin American Regional Contests 2019 I题
    UCF Local Programming Contest 2017 H题(区间dp)
    HDU2089 不要62
    AcWing1084 数字游戏II(数位dp)
    UCF Local Programming Contest 2017 F题(最短路)
    Google Code Jam 2019 Round 1A Pylons(爆搜+贪心)
    AcWing1083 Windy数(数位dp)
    Vue
  • 原文地址:https://www.cnblogs.com/alex96/p/12146277.html
Copyright © 2011-2022 走看看