zoukankan      html  css  js  c++  java
  • Python Django 学习 (二) 【Django 模型】

    注: 由于自己排版确实很难看,本文开始使用markdown编辑,希望有所改善

    官方定义

    A model is the single, definitive source of information about your data. It contains the essential fields and behaviors of the data you’re storing. Generally, each model maps to a single database table.

    一个模型是关于你的数据的单个的、确定的信息源。它包含了你储存数据的必要的列和行为,基本上,一个模型映射一个单个的数据库表。

    更改Django数据库配置

    由于原生的django使用的是sqlite3, 本人熟悉mysql 所以最后使用mysql。

    注:本文接着上一篇文章来的,如果没有相应的项目请按照上一篇内容操作一下。[Python Django 学习 (一) 【Django 框架初探】]

    • 在 test_project项目中找到文件 test_project/test_project/settings.py 找到如下代码
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.sqlite3',
            'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
        }
    }
    
    • 将上述代码注释掉,添加如下代码:
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': 'mysql',#数据库名字
            'USER':'root',
            'PASSWORD':'*****',
            'HOST':'localhost',
            'PORT':'3306',
        }
    } 
    
    • 确保一件事情,你的python3 的版本安装了 pymysql 、mysqlclient 使用pip 安装
    pip3.6 install pymysql
    pip3.6 install mysqlclient 
    # 我在安装mysqlclient时出现了问题,到 https://www.lfd.uci.edu找的包自己安装的
    

    创建 test_app

    在使用model时,官方文档说,“当你定了模型之后,你需要告诉Django你将使用这些模型。通过编辑setting.py中 INSTALL_APPS,将包含你的模型的app的名字放到里面”

    • 打开 CMD 键入 如下指令:
    python36 manage.py startapp test_app
    
    • 将会在 test_project项目下 新建一个 test_app文件目录

    • 作用说明

    文件名 作用
    migrations 将模型的更改,形成可执行的PY文件,使用指令迁移到数据库中
    _init_.py 标识当前文件路径是一个python包
    admin.py 可以在其中添加当前model,然后使用界面对数据库进行操作
    apps.py 当前app 配置
    models.py 存放当前app存在的模型,与数据库一一对应
    tests.py 存放当前app的测试
    views.py 存在当前app的页面模板
    • 将 test_app 添加到 test_project/test_project/settings.py文件中,如下:
    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        # new add 
        'test_app',
    ]
    

    添加 testmodel 到 test_app中、迁移到数据库

    • 打开 文件 test_project/test_app/modes.py 更改代码如下:
    from django.db import models
    # Create your models here.
    class TestModel(models.Model):
    	# django 有一个机制 在没有设置自增主键的时候会自动创建一个主键,
    	test_name = models.CharField(max_length=100, default='no_name') # 字符类型的字段 设置最大长度与默认值
    	test_content = models.CharField(max_length=50,default='male') # 字符类型的字段 设置最大长度与默认值
    	# 如果不指定表名,django默认表明是 'appname_classname'
    	class Meta:
    		'''
    		使用如下语句定义表名
    		db_table = 'test_model'
    		'''
    	def __unicode__(self):
    		return '%d: %s' % (self.pk, self.test_name)
    
    • 打开 CMD 键入 如下命令:
    python36 manage.py makemigrations #不指定app将迁移全部数据
    python36 manage.py makemigrations test_app # 可以选择单个app进行数据迁移
    #以上两个都可以,在app多的时候,建议使用下面的单个迁移
    #该命令只是生成迁移文件,并没有真正的操作数据库
    #######################################################################################
    #返回如下结果
    Migrations for 'test_app':
      test_appmigrations001_initial.py
        - Create model TestModel
    
    • 下面我查看文件夹 test_project est_appmigrations 增加了文件 0001_initial.py,第一次迁移文件名应该都是这个,之后会不同。查看 文件 0001_initial.py 内容如下:
    # Generated by Django 2.0 on 2018-11-15 03:00
    from django.db import migrations, models
    class Migration(migrations.Migration):
        initial = True
        dependencies = [
        ]
        operations = [
            migrations.CreateModel(
                name='TestModel',
                fields=[
                    ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                    ('test_name', models.CharField(default='no_name', max_length=100)),
                    ('test_content', models.CharField(default='male', max_length=50)),
                ],
            ),
        ]
    # 我们可以看到,钱 Migration类中,定义了新的 模型 TestModel,并且有三个字段 id、test_name、test_content
    
    • 我每次迁移的时候都会查看,生成的迁移文件,确保都是我想要的数据库改动。打开CMD 键入指令:
    python36 manage.py migrate
    #该指令将,真正将建表操作到mysql数据库中
    #######################################################################################
    #会看到如下提示
    Operations to perform:
      Apply all migrations: admin, auth, contenttypes, sessions, test_app
    Running migrations:
      Applying test_app.0001_initial... OK
    #可以发现执行了 刚才的 0001_initial.py 文件中的内容
    
    • 我们打开mysql 数据库查看,是否存在表
    mysql> show create table test_app_testmodel
        -> ;
    +--------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | Table              | Create Table                                                                                                                                                                                                                              |
    +--------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | test_app_testmodel | CREATE TABLE `test_app_testmodel` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `test_name` varchar(100) NOT NULL,
      `test_content` varchar(50) NOT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |
    +--------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    1 row in set (0.01 sec)
    
    • 至此,模型与数据库已经实现了同步。

    使用 django admin管理数据库数据

    • 之前说过 test_app下的文件 admin.py 添加如下内容:
    from django.contrib import admin
    
    from .models import TestModel
    # Register your models here.
    
    @admin.register(TestModel)
    class TestModelAdmin(admin.ModelAdmin):
        list_display = ('pk', 'test_name')    #在后台列表下显示的字段
    
    • 进入 django admin页面 输入超级用户用户名、密码

    • 通过 admin 管理 test model,点击上面的 Test models 可以通过页面进行增、删、改、查的操作

    介绍一下Django提供的字段类型

    • 基本类型
    AutoField #自增列,如果不存在的话会添加一个自增的ID列
    BigAutoField # 64位的,比上面自增列大
    BigIntegerField #64 位的整型
    BinaryField #原生的二进制列
    BooleanField#布尔
    CharField#字符串,注意该字段必须指定 max_length
    DateField#日期,可以指定auto_now 与 auto_now_add可以自动填充当前列为当前时间
    DateTimeField# datetime
    DecimalField# 小数点
    DurationField# 与python的timedelta对应
    EmailField
    FileField
    FileField and FieldFile
    FilePathField
    FloatField
    ImageField
    IntegerField
    GenericIPAddressField
    NullBooleanField
    PositiveIntegerField
    PositiveSmallIntegerField
    SlugField
    SmallIntegerField
    TextField
    TimeField
    URLField
    UUIDField
    # 不是所有的 field 都用过,有兴趣请自行尝试
    
    • ArrayField

    最近使用 Postgresql 开发,发现它支持,array类型。在Django,中同样支持,代码如下:

    
    class TestModel(models.Model):
        test_array = ArrayField(models.CharField(max_length=96, null=False, default=''), default="{}", size="99")
        # 意思为增加一个 test_array数组字段,并且数组元素都是char ,可以更换成其他类型
        #此处default {}是因为 postgresql在检测的时候强制插入数据为 '{a,b,c,d}',default空的话会报错
        class Meta:
            db_table = 'test_model'
        def __str__(self):
            return self.node
    

    代码中的增删改查

    • 分别在以下文件中添加如下代码,路由具体说明将会重新写一篇文章
    
    # test_project/test_project/urls.py
    from django.conf.urls import url
    from django.contrib import admin
    from django.urls import path,include
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        path('', include('test_app.urls')),#包括test_app的url
    ]
    
    #创建 test_project/test_app/urls.py
    from django.conf.urls import url
    from test_app import views
    urlpatterns = [
        url('test_app/test_model', views.test_model),
    ]
    
    # 需要定义一个查询的api
    # test_project/test_app/views.py
    from django.shortcuts import render
    from django.http import HttpResponse
    from . import models
    import json as json
    from django.core import serializers
    def test_model(request):
    	data  = models.TestModel.objects.all()
    	data_json = json.loads(serializers.serialize('json', data))#将queryset变成json输出
    	print(str(data_json))
    	return HttpResponse(data_json);	
    #启动Django服务后,在浏览器中输入 localhost:8000/test_app/test_model
    #打印结果将在cmd显示
    
    # 更换不同的查询方式,打印输出结果
    # 数据库中插入了两条数据
    models.TestModel.objects.all() #获取所有的数据 返回queryset
    models.TestModel.objects.all().values('test_name') #只取test_name列 返回queryset
    models.TestModel.objects.get("id=1") #只要id=1 返回object
    models.TestModel.objects.all().filter("id=2") #只要id=2 返回queryset
    models.TestModel.objects.all().exclude("id=2") #排除id=2 返回queryset
    #打印结果
    *******
    [{'model': 'test_app.testmodel', 'pk': 1, 'fields': {'test_name': 'name1', 'test_content': 'content1'}}, {'model': 'test_app.testmodel', 'pk': 2, 'fields': {'test_name': 'test2', 'test_content': 'content2'}}]
    *******
    <QuerySet [{'test_name': 'name1'}, {'test_name': 'test2'}]>
    *******
    TestModel object (1)
    *******
    [{'model': 'test_app.testmodel', 'pk': 2, 'fields': {'test_name': 'test2', 'test_content': 'content2'}}]
    *******
    <QuerySet [<TestModel: TestModel object (1)>]>
    *******
    #更细节的查询,官网查看吧
    https://docs.djangoproject.com/en/2.0/topics/db/queries/
    
    #更改 test_project/test_app/urls.py,添加对于增加数据的url配置
    from django.conf.urls import url
    from test_app import views
    urlpatterns = [
        url('test_app/test_model', views.test_model),
        # new add
        url('test_app/test_addto_model', views.add_test_model),
    ]
    
    #更改 test_project/test_app/views.py 新增如下函数代码
    def add_test_model(request):
        models.TestModel.objects.create(
                       test_name="name_add_by_code",test_content="content_add")
    	new_data = models.TestModel.objects.all()
    	new_data_json = json.loads(serializers.serialize('json', new_data))
    	return HttpResponse(new_data_json);
    #启动 django 服务后,访问链接 localhost:8000/test_app/test_addto_model
    
    页面输入结果:
    {'model': 'test_app.testmodel', 'pk': 1, 'fields': {'test_name': 'name1', 'test_content': 'content1'}}{'model': 'test_app.testmodel', 'pk': 2, 'fields': {'test_name': 'test2', 'test_content': 'content2'}}{'model': 'test_app.testmodel', 'pk': 3, 'fields': {'test_name': 'name_add_by_code', 'test_content': 'content_add'}}
    数据库查询结果
    mysql> select * from test_app_testmodel;
    +----+------------------+--------------+
    | id | test_name        | test_content |
    +----+------------------+--------------+
    |  1 | name1            | content1     |
    |  2 | test2            | content2     |
    |  3 | name_add_by_code | content_add  |
    +----+------------------+--------------+
    3 rows in set (0.00 sec)
    增加成功
    
    # 由于考虑到数据完整行,简单介绍一下 Django 的 【事物】
    from django.db import transaction
    with transaction.atomic():
        #数据库操作
    #上面是最简单的方法,过程中报错将不会操作数据库
    #详情参加官网:https://docs.djangoproject.com/en/2.0/topics/db/transactions/
    
    #不做演示了,直接上代码
    models.UserInfo.objects.filter(test_name='nam1').update(test_content='content1_update')
    
    #删除的时候一定要filter一下呦
    models.UserInfo.objects.filter(test_name='test2').delete()
    

    数据库结构的导入到代码

    1. 下载了项目代码,但是本地数据库中没有项目表结构
    2. 数据库在后台改动了,要同步到代码中
    python36 manage.py inspectdb
    

    注:在使用makemigrations 与 migrate时,每一次的 makemigrations 是基于上一个makemigrations进行比较的,如果某一次的makemigrations后,migrate失败,切记到 app下 migrations文件夹下删除,最新的makemigrations文件,然后修改model代码,重新makemigrations,否则将会报错一直迁移不到数据库中。被这个坑了好久。

  • 相关阅读:
    memcached整理の基本使用
    memcached整理の编译
    linux命令の删除文件和文件夹 复制粘贴文件和文件夹
    ANSIBLE工具
    RSYNC服务
    FTP服务
    Mac运维安装软件
    WebSocket协议
    TCP三次握手和四次挥手、HTTP协议
    GITBOOK/HEXO TRAVIS GITHUB-PAGES 博客搭建
  • 原文地址:https://www.cnblogs.com/primadonna/p/9982354.html
Copyright © 2011-2022 走看看