注: 因为本身排版确实很难看,本文开始使用markdown编辑,但愿有所改善html
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.node
一个模型是关于你的数据的单个的、肯定的信息源。它包含了你储存数据的必要的列和行为,基本上,一个模型映射一个单个的数据库表。python
因为原生的django使用的是sqlite3, 本人熟悉mysql 因此最后使用mysql。mysql
注:本文接着上一篇文章来的,若是没有相应的项目请按照上一篇内容操做一下。[Python Django 学习 (一) 【Django 框架初探】]sql
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', } }
pip3.6 install pymysql pip3.6 install mysqlclient # 我在安装mysqlclient时出现了问题,到 https://www.lfd.uci.edu找的包本身安装的
在使用model时,官方文档说,“当你定了模型以后,你须要告诉Django你将使用这些模型。经过编辑setting.py中 INSTALL_APPS,将包含你的模型的app的名字放到里面”数据库
python36 manage.py startapp test_app
将会在 test_project项目下 新建一个 test_app文件目录django
做用说明json
文件名 | 做用 |
---|---|
migrations | 将模型的更改,造成可执行的PY文件,使用指令迁移到数据库中 |
_init_.py | 标识当前文件路径是一个python包 |
admin.py | 能够在其中添加当前model,而后使用界面对数据库进行操做 |
apps.py | 当前app 配置 |
models.py | 存放当前app存在的模型,与数据库一一对应 |
tests.py | 存放当前app的测试 |
views.py | 存在当前app的页面模板 |
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', # new add 'test_app', ]
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)
python36 manage.py makemigrations #不指定app将迁移所有数据 python36 manage.py makemigrations test_app # 能够选择单个app进行数据迁移 #以上两个均可以,在app多的时候,建议使用下面的单个迁移 #该命令只是生成迁移文件,并无真正的操做数据库 ####################################################################################### #返回以下结果 Migrations for 'test_app': test_app\migrations\0001_initial.py - Create model TestModel
# 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
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> 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)
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页面 输入超级用户用户名、密码api
经过 admin 管理 test model,点击上面的 Test models 能够经过页面进行增、删、改、查的操做数组
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 都用过,有兴趣请自行尝试
最近使用 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()
python36 manage.py inspectdb
注:在使用makemigrations 与 migrate时,每一次的 makemigrations 是基于上一个makemigrations进行比较的,若是某一次的makemigrations后,migrate失败,切记到 app下 migrations文件夹下删除,最新的makemigrations文件,而后修改model代码,从新makemigrations,不然将会报错一直迁移不到数据库中。被这个坑了很久。