學習筆記,僅供參考,有錯必糾
數據庫和模型
Django中默認數據庫是SQLite數據庫,就是db.sqlite3文件。注意!數據庫一定是用文件來存儲的,只不過數據庫對這些文件進行了統一管理,並加入了一些事務和表的概念,會使我們操作起來更加方便。
Django下使用mysql數據庫
安裝pymysql包
在cmd中敲入下面的代碼,安裝pymysql:
pip install pymysql
我已經裝過了,在這裏就不演示了。
安裝mysql客戶端:
pip install mysqlclient
在這裏,我重新安裝了一下mysqlclient。
創建和配置數據庫
爲了學好這個知識點,我們先創建一個新的工程mywebsite_db:
F:\MyStudio\PythonStudio\goatbishop.project01\Django>django-admin startproject mywebsite_db
- 創建數據庫
語法:
create database 數據庫名 default charset utf8 collate utf8_general_ci;
上面這段代碼表示,創建一個utf8編碼的數據庫,且數據庫中的英文不區分大小寫。
現在,我們創建自己的數據庫mywebdb:
create database mywebdb default charset utf8 collate utf8_general_ci;
- 數據庫的配置
在settings.py文件中有一個DATABASES字典,如下所示:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
我們看到默認的數據庫引擎是sqlite3,默認的文件是db.sqlite3
如果,我們需要使用mysql數據庫,就需要對其進行配置:
DATABASES = {
# 'default': {
# 'ENGINE': 'django.db.backends.sqlite3',
# 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
# }
'default' : {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'mywebdb', # 數據庫名稱,需要自己定義
'USER': 'root',
'PASSWORD': '19970928', # 管理員密碼
'HOST': '127.0.0.1',
'PORT': 3306, #mysql端口號
}
}
這時,我們還需要添加對mysql的支持,也就是在mywebsite_db文件夾下的__init__.py
模塊中加入如下內容:
import pymysql
pymysql.install_as_MySQLdb()
- 數據庫的遷移
遷移是Django同步對模型所做的更改(添加字段,刪除模型等)到數據庫的一種方式。
遷移第1步:生成或更新遷移文件
python manage.py makemigrations
遷移第2步:執行遷移腳本程序(更新數據庫)
python manage.py migrate
最後,我們可以查看一下遷移執行的SQL語言(不必要):
python manage.py sqlmigrate
現在,我們進行數據庫遷移:
F:\MyStudio\PythonStudio\goatbishop.project01\Django\mywebsite_db>python manage.py makemigrations
這時,我們報了一個錯誤:
raise ImproperlyConfigured('mysqlclient 1.3.13 or newer is required; you have %s.
' % Database.__version__)
django.core.exceptions.ImproperlyConfigured: mysqlclient 1.3.13 or newer is required;
you have 0.9.3.
我在網上查了一下,準備採用改源代碼的方式解決我們的問題。解決方法
首先,註釋掉F:\software\Anaconda\Lib\site-packages\django\db\backends\mysql目錄下base.py文件中的下面這一部分(35 - 36行
):
version = Database.version_info
#if version < (1, 3, 13):
# raise ImproperlyConfigured('mysqlclient 1.3.13 or newer is required; you have %s.' % Database.__version__)
再找到和base.py一個文件夾下的operations.py文件,並將decode改爲encode:
def last_executed_query(self, cursor, sql, params):
# With MySQLdb, cursor objects have an (undocumented) "_executed"
# attribute where the exact query sent to the database is saved.
# See MySQLdb/cursors.py in the source distribution.
query = getattr(cursor, '_executed', None)
if query is not None:
query = query.decode(errors='replace')
return query
#--------改爲--------
def last_executed_query(self, cursor, sql, params):
# With MySQLdb, cursor objects have an (undocumented) "_executed"
# attribute where the exact query sent to the database is saved.
# See MySQLdb/cursors.py in the source distribution.
query = getattr(cursor, '_executed', None)
if query is not None:
query = query.encode(errors='replace')
return query
因爲不同版本的Django中,decode在不同的行,所以,大家可以自行搜索一下decode的具體位置,再進行修改。
現在,我們再運行一下
F:\MyStudio\PythonStudio\goatbishop.project01\Django\mywebsite_db>python manage.py makemigrations
No changes detected
很好!問題被完美解決!
好的,我們繼續運行下面這段代碼:
F:\MyStudio\PythonStudio\goatbishop.project01\Django\mywebsite_db>python manage.py migrate
運行完畢後,它生成了這麼一坨文件:
Operations to perform:
Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying admin.0003_logentry_add_action_flag_choices... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying auth.0009_alter_user_last_name_max_length... OK
Applying auth.0010_alter_group_name_max_length... OK
Applying auth.0011_update_proxy_permissions... OK
Applying sessions.0001_initial... OK
現在,我們到mysql中查看一下mywebdb數據庫中的數據表:
mysql> show tables;
+----------------------------+
| Tables_in_mywebdb |
+----------------------------+
| auth_group |
| auth_group_permissions |
| auth_permission |
| auth_user |
| auth_user_groups |
| auth_user_user_permissions |
| django_admin_log |
| django_content_type |
| django_migrations |
| django_session |
+----------------------------+
10 rows in set (0.00 sec)
很好,多了一堆數據表,這些數據表是Django幫我們創建的。
當我們看到這一堆數據表時,就表示,我們已經配置完成了!
模型(Model)
在MTV設計模式中,存在一個Model,它不是直接的數據庫,而是屬於服務器端的組成部分,Model可以和數據庫進行交互,所以,我們不需要直接操縱數據庫,而是操作模型就可以了。
模型概述
-
模型是提供數據信息的數據庫接口。
-
模型是數據的唯一的、確定的信息源。它包含我們所儲存數據的必要字段和行爲。
-
通常,每個模型對應數據庫中唯一的一張表。每個模型的實例對應數據表中的一條記錄。
-
模型說明:
- 每個模型都是一個Python類,每個模型都是django.db.models.Model的子類
- 每一個模型都代表數據庫中的一個表
- Django爲我們提供一個自動生成的數據庫訪問API,也就是說我們不需要使用sql語句,而只需要使用這些類,這樣就免去了直接使用sql語句的麻煩。
python數據庫模型-Models
- ORM框架
ORM(Object Relationship Mapping)即對象關係映射,它允許我們使用類和對象對數據庫進行交互。對象關係映射是指,我們表面上操作的是對象,實際上操作的是數據庫。
- ORM三大特徵
- 表到類的映射
- 數據類型的映射
- 關係映射
案例
我們在mywebdb工程下創建一個名爲bookstore的應用:
F:\MyStudio\PythonStudio\goatbishop.project01\Django\mywebsite_db>python manage.py startapp bookstore
並將其註冊到settings.py中:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'bookstore',
]
我們看到,bookstore文件夾下有一個models.py:
這個models.py就是專門用來存放模型的。
我們在models.py模塊中創建一個Book類(表),並定義一個字段(title):
from django.db import models
# Create your models here.
class Book(models.Model):
title = models.CharField("書名", max_length = 30)
Now! 我們在cmd中更新一下遷移文件:
F:\MyStudio\PythonStudio\goatbishop.project01\Django\mywebsite_db>python manage.py makemigrations
輸出:
Migrations for 'bookstore':
bookstore\migrations\0001_initial.py
- Create model Book
可以看到,Django創建了一個模型Book,並且在 bookstore\migrations路徑下創建了一個0001_initial.py
文件,現在,我們看一看這個文件:
# Generated by Django 2.2.13 on 2020-06-18 13:57
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Book',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=30, verbose_name='書名')),
],
),
]
可以看到,Django幫我們創建了一個模型叫Book,其中包含兩個字段(id和title)。
需要注意的是,此時,我們的mywebdb數據庫中沒有發生任何改變。
OK!我們回到cmd中,執行遷移:
F:\MyStudio\PythonStudio\goatbishop.project01\Django\mywebsite_db>python manage.py migrate
輸出:
Operations to perform:
Apply all migrations: admin, auth, bookstore, contenttypes, sessions
Running migrations:
Applying bookstore.0001_initial... OK
此時,我們回到mywebdb數據庫,顯示數據表,發現多了一個數據表bookstore_book:
mysql> show tables;
+----------------------------+
| Tables_in_mywebdb |
+----------------------------+
| auth_group |
| auth_group_permissions |
| auth_permission |
| auth_user |
| auth_user_groups |
| auth_user_user_permissions |
| bookstore_book |
| django_admin_log |
| django_content_type |
| django_migrations |
| django_session |
+----------------------------+
11 rows in set (0.00 sec)
我們desc一下這張數據表:
mysql> desc bookstore_book;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| title | varchar(30) | NO | | NULL | |
+-------+-------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)
可以看到兩個字段,一個id字段,它是主鍵,且是自增字段;還有一個是title字段,它是我們自己設定的字段。
此時,我們想在模型文件models.py中再加入一個字段(pub):
from django.db import models
# Create your models here.
class Book(models.Model):
title = models.CharField("書名", max_length = 30)
pub = models.CharField("出版社名", max_length = 50,null = True)
注意!只要我們修改了模型類,就必須要進行遷移:
F:\MyStudio\PythonStudio\goatbishop.project01\Django\mywebsite_db>python manage.py ma
kemigrations
Migrations for 'bookstore':
bookstore\migrations\0002_book_pub.py
- Add field pub to book
F:\MyStudio\PythonStudio\goatbishop.project01\Django\mywebsite_db>python manage.py mi
grate
Operations to perform:
Apply all migrations: admin, auth, bookstore, contenttypes, sessions
Running migrations:
Applying bookstore.0002_book_pub... OK
此時在查看mywebdb數據庫中的bookstore_book表:
mysql> desc bookstore_book;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| title | varchar(30) | NO | | NULL | |
| pub | varchar(50) | YES | | NULL | |
+-------+-------------+------+-----+---------+----------------+
3 rows in set (0.01 sec)
Very well!