python+Django的web应用程序(二)Django入门——创建应用程序

按照《Python编程:从入门到实践》这本书的项目三所编写的web应用程序

python+Django的web应用程序(二)Django入门

创建应用程序

这次先写一个程序练练手。

首先,要确保你的虚拟环境处于激活状态,并且Django服务正在运行

如果没有,那么先激活虚拟环境,在项目文件夹(learning_log)中打开cmd
在这里插入图片描述

输入命令:

ll_env\Scripts\activate 

执行结果:
在这里插入图片描述
然后,运行Django服务
命令如下:

python manage.py runserver

执行结果:
在这里插入图片描述

注:
退出Django服务: ctrl + c
退出虚拟环境: deacvivate

保持当前运行着runserver的cmd窗口,再另打开一个cmd窗口,切换到manage.py所在的目录,激活虚拟环境。再执行如下指令来创建应用程序:

python manage.py startapp learning_logs

执行结果:
在这里插入图片描述
看项目文件多了什么
在这里插入图片描述
打开新增的文件
在这里插入图片描述
没问题,和书上说的一模一样

定义模型

打开models.py文件
在这里插入图片描述
打开后
在这里插入图片描述
需要我们创建自己的模型。
这个模型会告诉Django如何处理应用程序中存储的数据。

模型就是类,在编程的世界里万物皆为类。类包含属性和方法。

接下来,我们创建一个存储主题的模型。这个模型包含一个容纳200个字符的主题名(text)和自动记录当前日期和时间的属性(date_added)。

代码如下:

from django.db import models

class Topic(models.Model):
    """用户学习主题"""
    text = models.CharField(max_length = 200)
    date_added = models.DateTimeField(auto_now_add = True)

    def __str__(self):
        """返回模型的字符串表示"""
        return self.text

在这里插入图片描述
方法__str__(),会返回存储在属性text中的字符串,从而显示模型的简单表示

注:如果使用的是python2,把__str__() 换成 unicode()

models中用到的方法:

  1. CharField:表示由字符或文本组成的数据

    			max_length :设定CharField的最大长度
    
  2. DateTimeField:记录日期和时间的数据

                auto_add_now=True:会自动设置成当前日期和时间
    

模型中可以使用的字段还有很多,可以去官网查找:
Django模型字段参考

激活模型

将我们写的模型安装在项目中,这样我们才能使用模型
首先,打开settings.py文件
在这里插入图片描述
打开后如图所示
在这里插入图片描述
INSTALLED_APPS 是一个元组,包含了所有Django的应用程序,我们只需要将自己写的应用程序添加进这个元组。
如下图所示
在这里插入图片描述

注:

  • 我们设置的settings.py是我们使用Django创建的项目(文件夹learning_log)
  • 而我们在settings.py中添加的是创建的应用程序(文件夹learning_logs)

现在我们写的模型已经包含进Django的项目中了。下一步,我们要让Django修改数据库,用于存储与模型相关的数据。
命令如下:

python manage.py makemigrations learning_logs

执行结果:
在这里插入图片描述

命令makemigrations : 让Django根据我们模型的属性修改数据库,使其能够存储与我们模型相关联的数据。

从执行结果上可以看到Django创建了一个名为0001_initial.py的迁移文件。
打开看看里面长啥样
文件位置如图所示
在这里插入图片描述
打开后
在这里插入图片描述
可以看到,里面有模型里的两个属性,text和date_added。

不过怎么多出来一个id?
我不记得我有写这个属性啊?
AutoField?意思是自动生成的吗?
不过多东西总比少东西强,大不了删掉完事。
额,有点担心乱删会出事。。。。总之还是问问度娘吧。

20分钟后。。。

还是度娘给力
总结如下:

为什么命令makemigrations生成的迁移文件会多出来一个id?

  • 这个id是主键(primary_key=True,这个参数值True表示这个是主键),你不设置主键,就会自动生成
  • Django需要主键
  • 主键是:被挑选出来,作表的行的唯一标识的候选关键字。
  • 主键的作用:
  1. 保证实体完整性(既每个数据表都必须有主键)
  2. 操作更便捷
  3. 避免重复(数据可能存在相同,但主键一定不同)
  4. 自动按顺序显示表中数据记录

如果我不想用自动生成的主键,我要用我自己的主键
按照度娘的指导试一下
在这里插入图片描述
建好自己的主键(同其他属性一样),只需多传一个参数

primary_key=True 

即可
别急着生成迁移文件

先把之前的迁移文件0001_initial.py给删了,不然会报错,报错如下:
在这里插入图片描述
删掉旧的迁移文件
在这里插入图片描述
再生成新的迁移文件(命令不变):

python manage.py makemigrations learning_logs

执行结果:
在这里插入图片描述
打开迁移文件看看
在这里插入图片描述
非常好,没有自动生成的id主键了,而是被我设置的my_id作为主键代替了。

好了,id这块搞懂了,还是把文件给还原为自动生成的id吧,我可不想后面因为我自己的改动出岔子。

复原后,下面来应用这种迁移,让Django替我们修改数据库
命令如下:

python manage.py migrate

执行结果:
在这里插入图片描述
最后一个OK代表learning_logs应用潜意识一切正常。

以后每次修改管理数据时,都是三步走:

  1. 修改models.py
    在这里插入图片描述
  2. 对learning_logs调用makemigrations
python manage.py makemigrations learning_logs
  1. 让Django迁移项目
python manage.py migrate

Django管理网站

Django提供的管理网站(admin site)可以帮助处理模型,这个管理网站管理员可用,普通用户不能。
下面将建立管理网站,并为模型添加一些主题。

创建超级用户

超级用户:拥有所有权限(想干啥就干啥那种),用于管理Web应用程序
创建超级用户命令:

 python manage.py createsuperuser

执行结果:在这里插入图片描述
创建后:
在这里插入图片描述

1 处:
密码太短,得有8个字符才行(This password is too short. It must contain at least 8 characters.)
密码太常见(This password is too common)
密码全是数字(This password is entirely numeric)
别设密码了,直接创建账号算了(Bypass password validation and create user anyway?)
2处:和1处一样

没错,我设的密码是六个0。因为复杂的密码我老是忘。再说了,我密码简单怎么了,我乐意,不行吗?
还有,为啥不设密码可以,密码简单不行?好家伙我直呼好家伙,密码再简单那也比没密码强啊。就跟大门敞开着和拿根麻绳捆着们把手一样,有总比没有强吧。

总之,如图所示,与其忘记密码,我选择不设密码。

向管理网站注册模型

Django自动在管理网站中添加了一些模型,如User和Group,但对于我们创建的模型,必须手动进行注册。

创建应用程序learning_logs时,Django在models.py所在的目录中创建了一个名为admin.py的文件
如图所示:
在这里插入图片描述
打开:
在这里插入图片描述
注册模型需要在admin.py中添加如下代码:

from learning_logs.models import Topic

admin.site.register(Topic)

在这里插入图片描述
这段代码导入模型并让Django通过管理网站管理我们的模型

现在,登录管理网站:
http://localhost:8000/admin/
网站如图所示:
在这里插入图片描述
输入用户名:ll_admin
因为没有设置密码,所以在密码栏输入你要设置的密码。
我敲了八个0,好记。

登陆后:
在这里插入图片描述

添加主题

点击Topics进入主题网页
在这里插入图片描述
因为我什么主题都没添加,所以这里面是空的,很正常。

点击添加主题
在这里插入图片描述
在这里插入图片描述
保存后:
在这里插入图片描述
主题添加成功
按书上要求,添加Chess(西洋棋)和Rock Climbing(攀岩运动)这两个主题
在这里插入图片描述
添加完毕

定义模型Entry

要记录西洋棋和攀岩运动的任何内容,需要为用户在笔记中添加的条目定义模型。每个条目都与特定主题相关联,这种关系被称为多对一关系,即多个条目可关联到同一个主题。

在models.py中添加模型Entry的代码:
代码如下

class Entry(models.Model):
    """学到的有关某个主题的具体知识"""
    topic = models.ForeignKey(Topic)
    text = models.TextField()
    date_added = models.DateTimeField(auto_now_add = True)

    class Meta:
        verbose_name_plural = 'entries'

    def __str__(self):
        """返回模型的字符串表示"""
        return  self.text[:50] + "..."

在这里插入图片描述

Meta类的verbose_name_plural看书上的介绍,说实话,没看太明白。
不过这都好说,谁让咱有度娘。

5分钟后…

总结如下:

verbose_name_plural属性:指定模型的复数形式是什么
若未指定该属性, Django 会使用 verbose_name + “s”
verbose_name:给主题起一个名字

看解释后,似乎verbose_name_plural的作用就是给你的复数主题起个你定义的名字
而verbose_name是给你的主题起一个名字

猜测一下:
现在的Entry模型,我不想让他在网站管理里面显示为Entry,我要给他起一个好理解的名字。这时可以使用 verbose_name = ’进入‘ ,那么网站管理里面的Entry的名字就会变成 进入
而更多的Entry模型的名字使用 verbose_name_plural = ’更多进入‘ ,那么网站管理里面的其他的Entry的名字就会变成 更多进入

好,现在来验证一下
在这里插入图片描述
woc什么情况,刚才还好好的,怎么和度娘问个事的功夫就出岔子了?

看下cmd
在这里插入图片描述
类型错误,缺少一个必要的参数on_delete

虽然指出了是在models.py里少了个参数,但这参数填哪里啊?
书上也没有这个参数啊

淦!!!

3分钟后…

总结如下:

异常描述:
少了个参数 ‘on_delete’(TypeError: init() missing 1 required positional argument: ‘on_delete’)

问题原因:
django生成迁移文件报错。django2.0以上版本,表与表之间关联的时候必须写 ’on_delete‘ 参数,不然会报错

解决办法:
因为是用外键和外表关联的,所以在外键上加上 ‘on_delete’ 参数,(有主建的模型都要加,Topic的主键是自动生成的,不用加。Entry的主键是我自己设置的,所以要加上)

外键就是models.ForeignKey()

代码如下:
在models.py文件中修改Entry类中的外键

topic = models.ForeignKey(Topic, on_delete = models.CASCADE)

在这里插入图片描述

on_delete = models.CASCADE
级联删除,自己的表和关联的表中的数据一起删除

on_delete还有一些其他的设置,网上很多,我觉得用这个就行

好了,再次运行我们的服务
在这里插入图片描述
成功启动服务了

登录网站管理看看名字改了没有
在这里插入图片描述
唉?别说了名了,我模型都没了?

翻了下前面的笔记,发现是没有进行数据迁移以及注册,不好意思,是我自己少步骤了。

迁移模型Entry

迁移命令有两个代码
先执行命令
python manage.py makemigrations 应用名
再执行命令
python manage.py migrate

代码如下:

python manage.py makemigrations learning_logs
python manage.py migrate

在提示一下,要在项目文件夹的激活环境下:
错误示范:
在这里插入图片描述
正确位置:
在这里插入图片描述
执行命令:
在这里插入图片描述
执行成功

向管理网站注册Entry

修改admin.py
admin.py的位置
在这里插入图片描述
打开修改
在这里插入图片描述
好了,Entry既迁移了,也注册了。看看网站管理上正确显示没
在这里插入图片描述
再修改一下models.py的代码
在这里插入图片描述
管理网站页面变化:
在这里插入图片描述
Entry的显示名成功修改为 多个进入
但是只有verbose_name_plural属性起了作用,verbose_name完全没效果。

5分钟后…

总结如下:

verbose_name是在添加模型显示对应的名称
verbose_name_plural是在网站管理页面显示对应的名称

比如我这样修改:
在这里插入图片描述
模型添加结果如下:
在这里插入图片描述
在这里插入图片描述
由图可见,verbose_name属性实在模型添加页面显示的。
(这个添加页面所添加的东西叫做条目)

接下来按照书上要求添加条目
在这里插入图片描述
添加成功
在这里插入图片描述

Django shell

可以通过互交式终端会话以编程方式查看输入的数据,这种互交式环境称为Django shell,非常适合测试项目和排除故障。
互交式shell会话示例:
在这里插入图片描述
最终返回的一个列表,称之为查询集(queryset)
代码如下:
启动Python解释器

python manage.py shell

导入模块块learning_logs.models中的模型Topic

from learning_logs.models import Topic

获取模型Topic的所有实例

Topic.objects.all()

对查询集的操作

  1. 遍历查询集
    类似遍历列表
    在这里插入图片描述

  2. 通过id获取对象的属性
    在这里插入图片描述

  3. 查看与主题相关联的条目
    因为给模型Entry定义了属性topic,这是一个外键(ForeignKey),将条目与主题关联起来。利用这种关联,Django能够获取与特定主题相关联的所有条目。
    通过外键关系获取数据,可使用相关模型的小写名称、下划线和单词set
    例:条目.模型_set.all()
    如下图所示:
    在这里插入图片描述
    奇怪,怎么什么都没有?
    难道是因为我是用Entry外键外联的Topic,而Topic没有外键,所以程序以为没有外联数据?
    总之试一试查看Entry的属性再说。

代码如下:

先遍历一下

>>> from learning_logs.models import Entry
>>> Entry.objects.all()
>>> entries = Entry.objects.all()
>>> for entry in entries:
...     print(entry.id,entry)

执行结果:
在这里插入图片描述可以遍历出来
好吧,其实到这里我已经看出来问题出在哪里了。不过还是吧代码写完再说吧

代码如下:

>>> e = Entry.objects.get(id=2)
>>> e.text
>>> e.date_added

执行结果:
在这里插入图片描述

接着写查看与主题相关联条目的代码:

e.topic_set.all()

执行结果:
在这里插入图片描述
属性错误:“Entry”对象没有属性“topic_set”(AttributeError: ‘Entry’ object has no attribute ‘topic_set’)

显然,模型_set.all()只查询被别人关联,不会查询出自身关联的别人

  1. 查看被关联的项目
    只有 id:2 与 id :3 与Entry相关联,id:1没有关联,故外键关系为空
    代码如下:

>>> t = Topic.objects.get(id=3)
>>>> t.entry_set.all()

执行结果:
在这里插入图片描述
成功查找到关联

注:
ctrl + Z 退出
每次修改模型后shell要重启

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值