关于“Python”的核心知识点整理大全59

简介: 关于“Python”的核心知识点整理大全59

4e6b9a6ad240581da0d33e03739ef8b5_cc3ef289c528468f95d68ee698dab5e6.png

19.3.2 将数据关联到用户

现在,需要将数据关联到提交它们的用户。我们只需将最高层的数据关联到用户,这样更低 层的数据将自动关联到用户。例如,在项目“学习笔记”中,应用程序的最高层数据是主题,而 所有条目都与特定主题相关联。只要每个主题都归属于特定用户,我们就能确定数据库中每个条 目的所有者。


下面来修改模型Topic,在其中添加一个关联到用户的外键。这样做后,我们必须对数据库 进行迁移。最后,我们必须对有些视图进行修改,使其只显示与当前登录的用户相关联的数据。


1. 修改模型Topic

对models.py的修改只涉及两行代码:


models.py

from django.db import models
from django.contrib.auth.models import User
class Topic(models.Model):
 """用户要学习的主题"""
 text = models.CharField(max_length=200)
 date_added = models.DateTimeField(auto_now_add=True)
 owner = models.ForeignKey(User)
 def __str__(self):
 """返回模型的字符串表示"""
 return self.text
class Entry(models.Model):
 --snip--

我们首先导入了django.contrib.auth中的模型User,然后在Topic中添加了字段owner,它建 立到模型User的外键关系。


2. 确定当前有哪些用户

我们迁移数据库时,Django将对数据库进行修改,使其能够存储主题和用户之间的关联。为 执行迁移,Django需要知道该将各个既有主题关联到哪个用户。最简单的办法是,将既有主题都 关联到同一个用户,如超级用户。为此,我们需要知道该用户的ID。


下面来查看已创建的所有用户的ID。为此,启动一个Django shell会话,并执行如下命令:


(venv)learning_log$ python manage.py shell
1 >>> from django.contrib.auth.models import User
2 >>> User.objects.all()
[<User: ll_admin>, <User: eric>, <User: willie>]
3 >>> for user in User.objects.all():
... print(user.username, user.id)
...
ll_admin 1
eric 2
willie 3
>>>

在1处,我们在shell会话中导入了模型User。然后,我们查看到目前为止都创建了哪些用户 (见2)。输出中列出了三个用户:ll_admin、eric和willie。


在3处,我们遍历用户列表,并打印每位用户的用户名和ID。Django询问要将既有主题关联 到哪个用户时,我们将指定其中的一个ID值。


3. 迁移数据库

知道用户ID后,就可以迁移数据库了。


1 (venv)learning_log$ python manage.py makemigrations learning_logs
2 You are trying to add a non-nullable field 'owner' to topic without a default;
we can't do that (the database needs something to populate existing rows).
3 Please select a fix:
1) Provide a one-off default now (will be set on all existing rows)
2) Quit, and let me add a default in models.py
4 Select an option: 1
5 Please enter the default value now, as valid Python
The datetime and django.utils.timezone modules are available, so you can do e.g. timezone.now()
6 >>> 1
Migrations for 'learning_logs':
 0003_topic_owner.py:
 - Add field owner to topic

我们首先执行了命令makemigrations(见1)。在2处的输出中,Django指出我们试图给既有 模型Topic添加一个必不可少(不可为空)的字段,而该字段没有默认值。在3处,Django给我 们提供了两种选择:要么现在提供默认值,要么退出并在models.py中添加默认值。在4处,我们 选择了第一个选项,因此Django让我们输入默认值(见5)。


为将所有既有主题都关联到管理用户ll_admin,我输入了用户ID值1(见6)。并非必须使用 超级用户,而可使用已创建的任何用户的ID。接下来,Django使用这个值来迁移数据库,并生成 了迁移文件0003_topic_owner.py,它在模型Topic中添加字段owner。


现在可以执行迁移了。为此,在活动的虚拟环境中执行下面的命令:


(venv)learning_log$ python manage.py migrate
Operations to perform:
 Synchronize unmigrated apps: messages, staticfiles
 Apply all migrations: learning_logs, contenttypes, sessions, admin, auth
--snip--
Running migrations:
 Rendering model states... DONE
1 Applying learning_logs.0003_topic_owner... OK
(venv)learning_log$

Django应用新的迁移,结果一切顺利(见1)。


为验证迁移符合预期,可在shell会话中像下面这样做:


1 >>> from learning_logs.models import Topic
2 >>> for topic in Topic.objects.all():
... print(topic, topic.owner)
...
Chess ll_admin
Rock Climbing ll_admin
>>>

我们从learning_logs.models中导入Topic(见1),再遍历所有的既有主题,并打印每个主 题及其所属的用户(见2)。正如你看到的,现在每个主题都属于用户ll_admin。


注意

你可以重置数据库而不是迁移它,但如果这样做,既有的数据都将丢失。一种不错的做 法是,学习如何在迁移数据库的同时确保用户数据的完整性。如果你确实想要一个全新 的数据库,可执行命令python manage.py flush,这将重建数据库的结构。如果你这样做, 就必须重新创建超级用户,且原来的所有数据都将丢失。


19.3.3 只允许用户访问自己的主题

当前,不管你以哪个用户的身份登录,都能够看到所有的主题。我们来改变这种情况,只向 用户显示属于自己的主题。 在views.py中,对函数topics()做如下修改:


views.py

--snip--
@login_required
def topics(request):
 """显示所有的主题"""
 topics = Topic.objects.filter(owner=request.user).order_by('date_added')
 context = {'topics': topics}
 return render(request, 'learning_logs/topics.html', context)
--snip--

用户登录后,request对象将有一个user属性,这个属性存储了有关该用户的信息。代码 Topic.objects.filter(owner=request.user)让Django只从数据库中获取owner属性为当前用户的 Topic对象。由于我们没有修改主题的显示方式,因此无需对页面topics的模板做任何修改。 要查看结果,以所有既有主题关联到的用户的身份登录,并访问topics页面,你将看到所有 的主题。然后,注销并以另一个用户的身份登录,topics页面将不会列出任何主题。


19.3.4 保护用户的主题

我们还没有限制对显示单个主题的页面的访问,因此任何已登录的用户都可输入类似于 http://localhost:8000/topics/1/的URL,来访问显示相应主题的页面。


你自己试一试就明白了。以拥有所有主题的用户的身份登录,访问特定的主题,并复制该页 面的URL,或将其中的ID记录下来。然后,注销并以另一个用户的身份登录,再输入显示前述主 题的页面的URL。虽然你是以另一个用户登录的,但依然能够查看该主题中的条目。 为修复这种问题,我们在视图函数topic()获取请求的条目前执行检查:


views.py

from django.shortcuts import render
1 from django.http import HttpResponseRedirect, Http404
from django.core.urlresolvers import reverse
--snip--
@login_required
def topic(request, topic_id):
 """显示单个主题及其所有的条目"""
 topic = Topic.objects.get(id=topic_id)
 # 确认请求的主题属于当前用户
2 if topic.owner != request.user:
 raise Http404 
entries = topic.entry_set.order_by('-date_added')
 context = {'topic': topic, 'entries': entries}
 return render(request, 'learning_logs/topic.html', context)
--snip--

服务器上没有请求的资源时,标准的做法是返回404响应。在这里,我们导入了异常Http404 (见1),并在用户请求它不能查看的主题时引发这个异常。收到主题请求后,我们在渲染网页前 检查该主题是否属于当前登录的用户。如果请求的主题不归当前用户所有,我们就引发Http404 异常(见2),让Django返回一个404错误页面。


现在,如果你试图查看其他用户的主题条目,将看到Django发送的消息Page Not Found。在 第20章,我们将对这个项目进行配置,让用户看到更合适的错误页面。


19.3.5 保护页面 edit_entry


页面edit_entry的URL为http://localhost:8000/edit_entry/entry_id/,其中entry_id是一 个数字。下面来保护这个页面,禁止用户通过输入类似于前面的URL来访问其他用户的条目:


views.py


         

我们获取指定的条目以及与之相关联的主题,然后检查主题的所有者是否是当前登录的用 户,如果不是,就引发Http404异常。


19.3.6 将新主题关联到当前用户

当前,用于添加新主题的页面存在问题,因此它没有将新主题关联到特定用户。如果你尝试 添加新主题,将看到错误消息IntegrityError,指出learning_logs_topic.user_id不能为NULL。 Django的意思是说,创建新主题时,你必须指定其owner字段的值。


由于我们可以通过request对象获悉当前用户,因此存在一个修复这种问题的简单方案。请 添加下面的代码,将新主题关联到当前用户:


views.py

目录
相关文章
|
2月前
|
存储 搜索推荐 数据库
关于“Python”的核心知识点整理大全58
关于“Python”的核心知识点整理大全58
44 2
|
26天前
|
存储 Python 容器
Python新手入门,这些基础知识点你掌握了吗?
【6月更文挑战第12天】Python是新手友好的编程语言,具备解释型、面向对象、动态类型和跨平台特性。基础知识包括:变量(如整数、浮点数、字符串、列表、元组、字典和集合),运算符与控制流(如条件语句和循环),以及函数的定义与调用。要精通Python,还需学习更多如面向对象编程、模块、文件操作等内容。开始你的Python学习之旅吧!
|
5天前
|
缓存 网络协议 Linux
Linux、Python、计算机网络中的常见知识点
Linux、Python、计算机网络中的常见知识点
|
5天前
|
算法 Java Linux
python中的面试常考知识点
python中的面试常考知识点
|
1月前
|
数据采集 机器学习/深度学习 数据挖掘
python运用知识点说明
Python涵盖广泛,从基础语法(变量、数据类型、字符串操作)到高级特性(装饰器、迭代器、闭包)。常用库包括NumPy, Pandas(数据处理),Scikit-learn, TensorFlow(机器学习),Django, Flask(Web开发),Scrapy(网络爬虫)。应用于Web开发、数据分析、系统运维、游戏开发和网络爬虫。Python历经1.x、2.x到3.x版本,3.x引入重大更新,强调Unicode和函数打印等,与2.x不兼容。掌握这些能提升开发效率。【6月更文挑战第4天】
32 2
|
2月前
|
Python
最新用Python做一个变态版的《超级玛丽》游戏,面试必备知识点
最新用Python做一个变态版的《超级玛丽》游戏,面试必备知识点
最新用Python做一个变态版的《超级玛丽》游戏,面试必备知识点
|
2月前
|
数据可视化 Python
Python模型评估与选择:面试必备知识点
【4月更文挑战第17天】本文深入探讨了Python模型评估与选择在面试中的关键点,包括性能度量、过拟合与欠拟合识别、模型比较与选择、模型融合和偏差-方差权衡。强调了避免混淆评估指标、忽视模型验证和盲目追求高复杂度模型的常见错误,并提供相关代码示例,如交叉验证、网格搜索和超参数调优。通过理解这些概念和技巧,可在面试中展示出色的数据科学能力。
59 12
|
2月前
|
存储 JSON 数据格式
Python知识点——高维数据的格式化
Python知识点——高维数据的格式化
30 0
|
2月前
|
Python
Python知识点——文件和数据格式化
Python知识点——文件和数据格式化
23 0
|
2月前
|
存储 关系型数据库 数据库
关于“Python”的核心知识点整理大全62
关于“Python”的核心知识点整理大全62
40 4
关于“Python”的核心知识点整理大全62