Django(part20)--數據庫和模型

學習筆記,僅供參考,有錯必糾




數據庫和模型

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!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章