目录
Django3.0.3 版本--SQLite数据库的创建与数据库基本操作
Django3.0.3 版本--SQLite数据库的创建与数据库基本操作
数据库创建相关
- 默认的数据库使用SQLite,若想使用其他的数据库,就需要在settings.py里面进行修改
By default, the configuration uses SQLite. If you’re new to databases, or you’re just interested in trying Django, this is the easiest choice. SQLite is included in Python, so you won’t need to install anything else to support your database. When starting your first real project, however, you may want to use a more scalable database like PostgreSQL, to avoid database-switching headaches down the road. If you wish to use another database, install the appropriate database bindings and change the following keys in the DATABASES 'default' item to match your database connection settings: * ENGINE – Either 'django.db.backends.sqlite3', 'django.db.backends.postgresql', 'django.db.backends.mysql', or 'django.db.backends.oracle'. Other backends are also available. * NAME – The name of your database. If you’re using SQLite, the database will be a file on your computer; in that case, NAME should be the full absolute path, including filename, of that file. The default value, os.path.join(BASE_DIR, 'db.sqlite3'), will store the file in your project directory. If you are not using SQLite as your database, additional settings such as USER, PASSWORD, and HOST must be added. For more details, see the reference documentation for DATABASES.
- 创建完App后,根据settings.py里的设置内容,在数据库中创建表
1.$ python manage.py migrate
The migrate command looks at the INSTALLED_APPS setting and creates any necessary database tables according to the database settings in your mysite/settings.py file and the database migrations shipped with the app (we’ll cover those later). You’ll see a message for each migration it applies. If you’re interested, run the command-line client for your database and type \dt (PostgreSQL), SHOW TABLES; (MariaDB, MySQL), .schema (SQLite), or SELECT TABLE_NAME FROM USER_TABLES; (Oracle) to display the tables Django created.
- Creating models
Now we’ll define your models – essentially, your database layout, with additional metadata.
These concepts are represented by Python classes. Edit the polls/models.py file so it looks like this:
Example:
from django.db import models
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
class Choice(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
- Activating models
That small bit of model code gives Django a lot of information. With it, Django is able to:
* Create a database schema (CREATE TABLE statements) for this app.
* Create a Python database-access API for accessing Question and Choice objects.
But first we need to tell our project that the polls app is installed. #首先要告诉你的项目,polls这个app已经注册了,就是在settings里面添加过。
mysite/settings.py:
INSTALLED_APPS = [
'polls.apps.PollsConfig',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
确认APP已经注册过的情况下,可以运行:
$ python manage.py makemigrations polls
You should see something similar to the following:
Migrations for 'polls':
polls/migrations/0001_initial.py:
- Create model Choice
- Create model Question
- Add field question to choice
数据库有任何修改,都可以运行
By running makemigrations, you’re telling Django that you’ve made some changes to your models (in this case, you’ve made new ones) and that you’d like the changes to be stored as a migration.
- 数据迁移定义
There’s a command that will run the migrations for you and manage your database schema automatically - that’s called migrate,and we’ll come to it in a moment - but first, let’s see what SQL that migration would run.
-
The sqlmigrate command takes migration names and returns their SQL: 数据迁移之前,需要运行
$ python manage.py sqlmigrate polls 0001
You should see something similar to the following (we’ve reformatted it for readability):
BEGIN;---- Create model Choice--CREATE TABLE "polls_choice" (
"id" serial NOT NULL PRIMARY KEY,
"choice_text" varchar(200) NOT NULL,
"votes" integer NOT NULL);---- Create model Question--CREATE TABLE "polls_question" (
"id" serial NOT NULL PRIMARY KEY,
"question_text" varchar(200) NOT NULL,
"pub_date" timestamp with time zone NOT NULL);---- Add field question to choice--ALTER TABLE "polls_choice" ADD COLUMN "question_id" integer NOT NULL;ALTER TABLE "polls_choice" ALTER COLUMN "question_id" DROP DEFAULT;CREATE INDEX "polls_choice_7aa0f6ee" ON "polls_choice" ("question_id");ALTER TABLE "polls_choice"
ADD CONSTRAINT "polls_choice_question_id_246c99a640fbbd72_fk_polls_question_id"
FOREIGN KEY ("question_id")
REFERENCES "polls_question" ("id")
DEFERRABLE INITIALLY DEFERRED;
COMMIT;
- Now, run migrate again to create those model tables in your database:再次运行migrate ,用于创建模型对应的数据库库表。The migrate command takes all the migrations that haven’t been applied (Django tracks which ones are applied using a special table in your database called django_migrations) and runs them against your database - essentially, synchronizing the changes you made to your models with the schema in the database.
$ python manage.py migrate
Operations to perform: Apply all migrations: admin, auth, contenttypes, polls, sessionsRunning migrations: Rendering model states... DONE Applying polls.0001_initial... OK
- 后续数据库有任何改动,需要牢记以下三个步骤:
We’ll cover them in more depth in a later part of the tutorial,remember the three-step guide to making model changes: * Change your models (in models.py). * Run python manage.py makemigrations to create migrations for those changes * Run python manage.py migrate to apply those changes to the database.
调用数据库API
- 打开shell交互界面,可以调用数据库API,实现数据库内数据的增删改查:
我根据这个链接中的步骤,创建账户,调用API,但是打开shell界面,添加数据的时候,遇到了一点问题:https://www.zmrenwu.com/courses/hellodjango-blog-tutorial/materials/62/
- 创建账户:
(Python36) [root@8ee837cc23a4 myblog]# python manage.py createsuperuser
鐢ㄦ埛鍚� (leave blank to use 'root'): Katelyn
Error: That 鐢ㄦ埛鍚� is already taken.
鐢ㄦ埛鍚� (leave blank to use 'root'): ZW
鐢靛瓙閭欢鍦板潃: 981791669@qq.com
Password:
Password (again):
Superuser created successfully.
- 打开shell:
(Python36) [root@8ee837cc23a4 myblog]# python manage.py shell
Python 3.6.2 |Continuum Analytics, Inc.| (default, Jul 20 2017, 13:51:32)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-1)] on linux
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from blog.models import Category,Tag,Post //需要导入在models.py中定义过的类,每次进入都需要重新导入
>>> from django.utils import timezone
>>> from django.contrib.auth.models import User
>>> user = User.object.get(username='myuser')
Traceback (most recent call last):
File "<console>", line 1, in <module>
AttributeError: type object 'User' has no attribute 'object' //这里是因为输入的命令有错误,是User.objects.get()
//但是这里我遇到的真正问题是,没有执行 python manage.py sqlmigrate blog 0001
>>> user = User.object.get(username='Katelyn')
Traceback (most recent call last):
File "<console>", line 1, in <module>
AttributeError: type object 'User' has no attribute 'object'
>>> user = User.object.get(username='test')
Traceback (most recent call last):
File "<console>", line 1, in <module>
AttributeError: type object 'User' has no attribute 'object'
>>> from django.contrib.auth.models import User
>>> user =User.object.get(username = 'test')
Traceback (most recent call last):
File "<console>", line 1, in <module>
AttributeError: type object 'User' has no attribute 'object' //这三个用户名都注册过,但是就是显示type object 'User' has no attribute 'object'
>>> quit()
后续,查阅文档后:
(Python36) [root@8ee837cc23a4 myblog]# python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, blog, contenttypes, sessions
Running migrations:
No migrations to apply.
(Python36) [root@8ee837cc23a4 myblog]# python manage.py sqlmigrate blog 0001
BEGIN;
--
-- Create model Category
--
CREATE TABLE "blog_category" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varchar(256) NOT NULL);
--
-- Create model Tag
--
CREATE TABLE "blog_tag" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varchar(70) NOT NULL);
--
-- Create model Post
--
CREATE TABLE "blog_post" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "title" varchar(128) NOT NULL, "body" text NOT NULL, "created_time" datetime NOT NULL, "modified_time" datetime NOT NULL, "excerpt" varchar(200) NOT NULL, "author_id" integer NOT NULL REFERENCES "auth_user" ("id") DEFERRABLE INITIALLY DEFERRED, "category_id" integer NOT NULL REFERENCES "blog_category" ("id") DEFERRABLE INITIALLY DEFERRED);
CREATE TABLE "blog_post_tags" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "post_id" integer NOT NULL REFERENCES "blog_post" ("id") DEFERRABLE INITIALLY DEFERRED, "tag_id" integer NOT NULL REFERENCES "blog_tag" ("id") DEFERRABLE INITIALLY DEFERRED);
CREATE INDEX "blog_post_author_id_dd7a8485" ON "blog_post" ("author_id");
CREATE INDEX "blog_post_category_id_c326dbf8" ON "blog_post" ("category_id");
CREATE UNIQUE INDEX "blog_post_tags_post_id_tag_id_4925ec37_uniq" ON "blog_post_tags" ("post_id", "tag_id");
CREATE INDEX "blog_post_tags_post_id_a1c71c8a" ON "blog_post_tags" ("post_id");
CREATE INDEX "blog_post_tags_tag_id_0875c551" ON "blog_post_tags" ("tag_id");
COMMIT;
//到这里才算是激活了
之后打开shell:
>>> from blog.models import Category,Tag,Post
>>> c=Category.objects.get(id=1) //可以用get.(id=1)查询到第一个创建成功的数据
>>> p =Post(title='title test',body='body test',created_time=timezone.now(),modified_time=timezone.now(),category=c,author=user)
>>> p.save() //每一次创建的时候都需要保存
>>> Post.objects.all() //可以通过 Post(类名).objects.all()查询所有数据
<QuerySet [<Post: title test>]>
>>> Tag.objects.all()
<QuerySet [<Tag: tag test>, <Tag: tag test>]>
>>> Category.objects.all()
<QuerySet [<Category: category test>, <Category: category test>]>
>>> c= Category.objects.get(id=1)
>>> c.name = 'category test new'
>>> c.save()
>>> Category.objects.all()
<QuerySet [<Category: category test new>, <Category: category test>]>
>>> a =Category.objects.get(id=2)
>>> a
<Category: category test>
>>> a.delete()
(1, {'blog.Category': 1})
>>> Category.objects.all()
<QuerySet [<Category: category test new>]>
//尝试在创建语句中不使用刚创建的变量,发现不行:
>>> from blog.models import Category,Tag,Post
>>> from django.utils import timezone
>>> p = Post(title='title test',body='body test',created_time=timezone.now(),modified_time=timezone.now().category=Category.objects.get(id=1),author=User.objects.get(id=1))
File "<console>", line 1
p = Post(title='title test',body='body test',created_time=timezone.now(),modified_time=timezone.now().category=Category.objects.get(id=1),author=User.objects.get(id=1)) ^
SyntaxError: invalid syntax
只能通过先取出值,存在变量里面的方式:
>>> c=User.objects.get(id=3)
>>> c
<User: test>
>>> c.delete() //删除数据
(2, {'admin.LogEntry': 0, 'auth.User_groups': 0, 'auth.User_user_permissions': 0, 'blog.Post_tags': 0, 'blog.Post': 1, 'auth.User': 1}) //会连带将包含该数据的其他数据也删掉,比如这里的Post:'blog.Post': 1
>>> c
<User: test>
>>> user = User.objects.all()
>>> user //可以直接查看变量值
<QuerySet [<User: Katelyn>]>
>>> c = Category.objects.get(name='category test') //查询类中name='category test' 的数据
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/root/anaconda3/envs/Python36/lib/python3.6/site-packages/django/db/models/manager.py", line 82, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/root/anaconda3/envs/Python36/lib/python3.6/site-packages/django/db/models/query.py", line 417, in get
self.model._meta.object_name
blog.models.Category.DoesNotExist: Category matching query does not exist. //不存在时候会直接提示
>>> Category.objects.all()
<QuerySet [<Category: category test new>]>
>>> c=Category.objects.get(id=1)
>>> c
<Category: category test new>
>>> p =Post(title='title test',body='body test',created_time=timezone.now(),modified_time=timezone.now(),category=c,author=user)
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/root/anaconda3/envs/Python36/lib/python3.6/site-packages/django/db/models/base.py", line 482, in __init__
_setattr(self, field.name, rel_obj)
File "/root/anaconda3/envs/Python36/lib/python3.6/site-packages/django/db/models/fields/related_descriptors.py", line 219, in __set__
self.field.remote_field.model._meta.object_name,
ValueError: Cannot assign "<QuerySet [<User: Katelyn>]>": "Post.author" must be a "User" instance. //这里的user没有定义过,所以需要重新获取一下
>>> p
Traceback (most recent call last):
File "<console>", line 1, in <module>
NameError: name 'p' is not defined
//成功的操作:
c已经在上面获取过了
>>> user=User.objects.get(id=1)
>>> user
<User: Katelyn>
>>> p =Post(title='title test',body='body test',created_time=timezone.now(),modified_time=timezone.now(),category=c,author=user)
>>> p
<Post: title test>
>>> p.save()
>>> Post.objects.all()
<QuerySet [<Post: title test>]>