032Django上手建立数据库

文章目录

    • 恢复工作
    • 数据库配置
    • 创建模型
    • 激活模型
      • 配置`INSTALLED_APPS `
      • 准备迁移 `makemigrations polls`
      • 执行迁移 `migrate`
    • 初试API
      • 交互式python命令行
      • 修改: 增加可读性
      • 使用示例
    • 创建管理员账户
    • 启动开发服务器

本上手项目的目的是:创建一个基本的投票应用程序。
它由两部分组成:

一个让人们查看和投票的公共站点。
一个让你能添加、修改和删除投票的管理站点。

本博客参考官方文档建立数据库部分:参考链接

项目环境:python==3.8.10, Django==3.2.6

恢复工作

首先,恢复上一步的工作,用于复习和准备环境:

  • cmd执行下列命令,创建项目
python -m django --version      # 查看Django版本

# cd 到一个你想放置你代码的目录后,执行
django-admin startproject mysite  #在当前目录下创建一个 mysite 目录

# 在外层mystie目录,执行
python manage.py runserver    #启动 Django 自带的用于开发的简易服务器

此时可以访问页面: http://127.0.0.1:8000/
注意,不是https

  • 创建项目中的一个应用
    在 Django 中,每一个应用都是一个 Python 包.项目则包含这些应用.
    执行以下代码继续:
# cd到外层mystie目录
python manage.py startapp polls    #创建一个polls应用,此时有了目录

定义一个 Django 中最简单的视图。打开 polls/views.py ,把下面这些 Python 代码输入进去:

from django.http import HttpResponse

def index(request):
    return HttpResponse("Hello, world. You're at the polls index.")

为了看见它,我们需要将一个 URL 映射到它(也就是URLconf)。新建 polls/urls.py 文件,然后打开,输入如下代码:

from django.urls import path
from . import views

urlpatterns = [
    path('', views.index, name='index'),
]

为了登记这个映射,还要在根 URLconf 文件中指定我们创建的 polls.urls 模块。打开 mysite/urls.py 文件,插入一个 include()来引用上面的URLconf, 如下:

from django.contrib import admin
from django.urls import include, path

urlpatterns = [
    path('polls/', include('polls.urls')),
    path('admin/', admin.site.urls),
]

注意,list中2个次序很重要.

  • cmd重启项目
python manage.py runserver

浏览器访问http://localhost:8000/polls/
注意,不是 http://localhost:8000/
032Django上手建立数据库_第1张图片

数据库配置

数据库配置参照另一篇博文:0322Django连接mysql数据库
Python 内置 SQLite,本次使用 SQLite 数据库.

创建模型

  • 打开 mysite/settings.py
TIME_ZONE = 'Asia/Shanghai'

文件头部的 INSTALLED_APPS 设置项:

这里包括了会在你项目中会启用的所有 Django 应用。 它默认包括了多个 Django 的自带应用,如果你不需要某个或某些应用,可以注释或删除。

  • cmd执行创建表: python manage.py migrate
    这个 migrate 命令检查 INSTALLED_APPS 设置,为其中的每个应用创建需要的数据表.

写一个数据库驱动的 Web 应用的第一步是定义模型.Django 里,你只需要定义数据模型.

这里需要创建两个模型:问题 Question 和选项 Choice。
Question 模型包括问题描述和发布时间。
Choice 模型有两个字段,选项描述和当前得票数。这些选项属于一个问题。

  • 编辑 polls/models.py 文件
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)

其中:

Question,Choice被表示为 django.db.models.Model 类的子类,类变量如question_text,pub_date 等表示模型里的一个数据库字段,将作为数据库的列名。
 
类变量(字段)是 Field 类的实例 - 比如,字符字段被表示为 CharField ,日期时间字段被表示为 DateTimeField 。这将告诉 Django 每个字段要处理的数据类型。
 
pub_date = models.DateTimeField('date published')中,使用可选的选项来为 Field 定义了一个人类可读的名字.
Choice中,我们使用 ForeignKey 定义了一个关系。这将告诉 Django,每个 Choice 对象都关联到一个 Question 对象。
 
其中,某些 Field 类实例需要参数,例如 CharField 需要一个 max_length 参数。
Field也能够接收多个可选参数,在上面的例子中:我们将 votes 的 default 也就是默认值,设为0。

激活模型

经由创建模型的代码,Django 可以:

为这个应用创建数据库 schema(生成 CREATE TABLE 语句)。
创建可以与 Question 和 Choice 对象进行交互的 Python 数据库 API。

配置INSTALLED_APPS

打开 mysite/settings.py
首先,为了在我们的工程中包含poll应用,我们需要在配置类 INSTALLED_APPS 中添加设置。

INSTALLED_APPS = [
   'polls.apps.PollsConfig', # 增加的app声明
    ]

准备迁移 makemigrations polls

cmd运行命令: python manage.py makemigrations polls ,会看到类似于下面这样的输出

Migrations for 'polls':
polls/migrations/0001_initial.py
  - Create model Question
  - Create model Choice

运行 makemigrations 命令,Django 会检测你对模型文件的修改,并且把修改的部分储存为一次 迁移。模型的迁移数据,被储存在 polls/migrations/0001_initial.py 里.

  • 迁移命令会执行一些 SQL 语句,这些语句可通过cmd命令查看:
    python manage.py sqlmigrate polls 0001

其中,数据库表名为: polls_question,polls_choice,即应用名(polls)和模型名的小写形式( question 和 choice)连接.
外键字段名后追加字符串 “_id” ,即question_id

执行迁移 migrate

再次运行 migrate 命令,在数据库里创建模型的数据表
python manage.py migrate
Django 通过在数据库中创建一个特殊的表 django_migrations, 来跟踪执行过哪些迁移. 这个 migrate 命令选中所有还没有执行过的迁移,并应用在数据库上 。也就是同步。
总结下,改变模型需要这三步:

编辑 models.py 文件,改变模型。
运行 python manage.py makemigrations 为模型的改变生成迁移文件。
运行 python manage.py migrate 来应用数据库迁移。

如上,数据库迁移被分解成生成和应用两个命令.

初试API部分请移步官方文档 : 初试API

初试API

交互式python命令行

cmd输入: python manage.py shell
这个命令会设置 Python 包的导入路径。

>>> from polls.models import Choice,Question
>>> Question.objects.all()      # 用于查看现有的问题对象
<QuerySet []>
>>> from django.utils import timezone
>>> q = Question(question_text="What is new ?", pub_date = timezone.now())   #创建一个Question对象
>>> q.save()    # 须显式保存,才能保存进数据库
>>> q.id           # 保存后就有id了,此外还有字段名:question_text,pub_date
1
>>> q.question_text    
'What is new ?'
>>> q.pub_date
datetime.datetime(2021, 8, 11, 8, 58, 38, 559463, tzinfo=<UTC>)
>>> q.question_text="what is up ?"     #此时q还是q, id未变. 其实是更改question_text字段罢了
>>> q.save()              	# 保存更改
>>> Question.objects.all()        
<QuerySet [<Question: Question object (1)>]>

创建,检索对象参考:检索对象

修改: 增加可读性

为了更好的展示Question的内容,避免出现这样的非人读的显示,我们对两个类(Question,Choice)增加魔法函数__str__():

from django.db import models
import datetime
from  django.utils import timezone

class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField("date published")

    def __str__(self):
        return self.question_text
    def was_published_recently(self):
        return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
        # 看当前问题的推出日期,是否大于当前时间的前一天. 也即,是否是前一天内推出的
class Choice(models.Model):
    question = models.ForeignKey(Question,on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)

    def __str__(self):
        return self.choice_text

使用示例

重启python交互行,进行测试:

...\mysite>python manage.py shell
Python 3.8.10 | packaged by conda-forge | (default, May 11 2021, 06:25:23) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from polls.models import Choice,Question
>>> Question.objects.all()       #显示发生了变化
<QuerySet [<Question: what is up ?>]>  

>>> Question.objects.filter(id=1)   # 相当于where语句,详情见码块外参考
<QuerySet [<Question: what is up ?>]>
>>> Question.objects.get(id=1)     # 俺也一样
<Question: what is up ?>
>>> Question.objects.get(id=2)
Traceback (most recent call last):
	...
polls.models.Question.DoesNotExist: Question matching query does not exist.
>>> Question.objects.get(pk=1)    # 俺也一样,pk:primary key
<Question: what is up ?>


>>> Question.objects.filter(question_text__startswith='What')  #这里用双下划线__调用了models.Model的对象方法startswith
<QuerySet [<Question: what is up ?>]>

>>> from django.utils import timezone
>>> current_year = timezone.now().year  #这是一个struct_time对象吧
>>> current_year
2021

>>> Question.objects.get(pub_date__year=current_year)  # 可见DateTimeField是类似于struct_time的
<Question: what is up ?>

>>> q = Question.objects.get(id=1)   
>>> q.was_published_recently()   # 自定义方法,判断是一天内发布的不?
True

>>> q.choice_set.all()		# 查看问题的选项,暂时没有,注意: 主表查询次表
<QuerySet []>
>>> q.choice_set.create(choice_text='Not Much',votes=0)  # 创建选项,4个
<Choice: Not Much>
>>> q.choice_set.create(choice_text='The Sky',votes=0)
<Choice: The Sky>
>>> q.choice_set.create(choice_text='Just Soso',votes=0)
<Choice: Just Soso>
>>> c =q.choice_set.create(choice_text='Just Soso',votes=0)
>>> c.question			# 查该选项隶属的问题, 注意: 次表查询主表
<Question: what is up ?>

>>> q.choice_set.all()   # 可以查到了,q问题有4个选项
<QuerySet [<Choice: Not Much>, <Choice: The Sky>, <Choice: Just Soso>, <Choice: Just Soso>]>
>>> q.choice_set.count()
4

>>> Choice.objects.filter(question__pub_date__year=current_year)  # 次表join主表来查询,返回pub_date在current_year发布的question的Choice对象
<QuerySet [<Choice: Not Much>, <Choice: The Sky>, <Choice: Just Soso>, <Choice: Just Soso>]>

>>> c2 = q.choice_set.filter(choice_text__startswith='Just')  # 查q的选项中以Just开头的 
>>> c2
<QuerySet [<Choice: Just Soso>, <Choice: Just Soso>]>
>>> c2.delete()    #返回一个元组,分别指示删除的选项数,和剩余的部分
(2, {'polls.Choice': 2})
>>> q.choice_set.count()
2

制定 SQL WHERE 子句, QuerySet 方法 filter(), exclude() 和 get()等详细参考:字段查询

创建管理员账户

cmd执行: python manage.py createsuperuser
然后,会自动跳出问题,依次填用户名,邮件地址,密码和确认一次.

启动开发服务器

首先启动服务: cmd执行 python manage.py runserver
然后,转到本地域名的admin目录:http://127.0.0.1:8000/admin/
登录,显示组和用户。它们是由 django.contrib.auth 提供的,这是 Django 开发的认证框架。
为了显示Question对象,我们需要更改polls.admin.py文件:

  • 打开 polls/admin.py 文件
from django.contrib import admin
from .models import Question

admin.site.register(Question)

然后就可以看到Question选项卡了.这是一个管理页面,由网站管理员使用的.

生成一个用户添加,修改和删除内容的后台是一项缺乏创造性和乏味的工作。因此,Django 全自动地根据模型创建后台界面。

埋下Bug钥匙~后续可能用到:

在进行数据迁移前,可以试试运行 python manage.py check ;这个命令帮助你检查项目中的问题,并且在检查过程中不会对数据库进行任何操作。参考

你可能感兴趣的:(项目,笔记,django,python,数据库)