行业知识
用Django 写学习笔记程序第二章.3让用户拥有自己的数据
文章目录
- 往期回顾
- 让用户拥有自己的数据
- 使用@login_required 限制访问
- 限制对 topics 页面的访问
- 将数据关联到用户
- 修改 Topic模型,在其中添加一个关联到用户的外键。
- 确定当前有哪些用户
- 迁移数据库
- 只允许用户访问自己的主题
- 保护用户的主题
- 保护页面 edit_entry
- 将���主题关联到当前用户
往期回顾
学习Django编写“学习笔记”程序
用Django 写学习笔记程序第二章.1 让用户能够输入数据
用Django 写学习笔记程序第二章.2 创建用户账户
详细内容请移步主页查看
让用户拥有自己的数据
用户应该能输入其专有的数据,为此,我们创建一个系统,确定各项数据据所属的用户,再限制对页面的访问,让用户只能使用自己的数据。
本期内容中,我们将修改Topic模型,让每个主题都归属于特定的用户。这一改动也会影响条目,因为每个条目都属于特定的主题。我们先限制对一些页面的访问。
使用@login_required 限制访问
Django 提供了装饰器 @login_required,让我们能够实现限制访问,对于某些页面,只允许已登录的用户访问。
装饰器(decorator) 是放在函数定义前面的指令。
限制对 topics 页面的访问
因为每个主题都归属于特定用户所有,因此只允许已登录的用户访问 topics页面。
from django.contrib.auth.decorators import login_required# 显示所有的主题@login_requireddef topics(request): topics = Topic.objects.order_by('date_added') content = {'topics': topics} return render(request, 'learning_logs/topics.html', content)code 说明:我们导入了函数 login_required,将它作为装饰器用于视图函数 topics()。在 topics() 之前加上@login_required,让python在运行 topics() 之前先运行它login_required() 检查用户是否已登录,仅当用户已登录时,Django才运行topics()
当用户未登录时,就重定向到页面:
修改 settings.py 让Django知道哪里去找登录页面。
LOGIN_URL = '/users/login/'
将数据关联到用户
将数据关联到提交他们的用户,我们只需将最高层的数据关联到用户,这样更低层的数据将自动关联到用户。
修改 Topic模型,在其中添加一个关联到用户的外键。
# models.py 的修改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
确定当前有哪些用户
迁移数据库时,Django将对数据库进行修改,使其能够存储主题和用户之间的关联。为了执行迁移,Django需要知道该将各个既有主题关联到哪个用户。
我们将既有主题都关联到同一个用户,即:超级用户
# 激活虚拟环境ll_env\Scripts\activate# 打开 shellpython manage.py shellfrom django.contrib.auth.models import UserUser.objects.all()for user in User.objects.all():print(user.username, user.id)用户名 1用户名 2用户名 3
迁移数据库
#迁移命令python manage.py makemigrations learning_logs# 之后会出现两个选项,两个选项皆选1
python manage.py migrate# 迁移成功后会报告 ..OK# 或者用 shell 查验python manage.py shellfrom learning_logs.models import Topicfor topic in Topic.objects.all():print(topic, topic.owner)
只允许用户访问自己的主题
当前,不管以哪个账号登录,都可以看到所有主题。
修改 views.py中 函数topics()
# 显示所有的主题@login_requireddef topics(request): topics = Topic.objects.filter(owner=request.user).order_by('date_added') content = {'topics': topics} return render(request, 'learning_logs/topics.html', content)request 对象有一个 user属性,该属性存储了有关用户的信息Topic.objects.filter(owner=request.user)让Django只从数据库中获取 owner属性为当前用户的Topic对象
保护用户的主题
from django.http import HttpResponseRedirect, Http404# 显示单个主题及其所有的条目@login_required()def topic(request, topic_id): topic = Topic.objects.get(id=topic_id) # 确认请求的主题属于当前用户 if topic.owner != request.user: raise Http404 entries = topic.entry_set.order_by('-date_added') content = {'topic': topic, 'entries': entries} return render(request,'learning_logs/topic.html', content)保护页面 edit_entry
# 编辑既有条目@login_requireddef edit_entry(request, entry_id): entry = Entry.objects.get(id=entry_id) topic = entry.topic if topic.owner != request.user: raise Http404 if request.method != 'POST': form = EntryForm() else: form = EntryForm(instance=entry, data=request.POST) if form.is_valid(): form.save() return HttpResponseRedirect(reverse('learning_logs:topic', args=[topic.id])) content = {'entry': entry, 'topic': topic, 'form': form} return render(request, 'learning_logs/edit_entry.html', content)将新主题关联到当前用户
用于添加新主题的页面存在问题,因此它没有将新主题关联到特定用户。如果尝试添加新的主题,就会出现错误消息 InterityError 的报错信息。指出learning_logs_topic.user_id 不能为NULL
Django的意思是说,添加新的主题时 必须指定其 owner字段的值,
由于我们可通过 request 获悉当前对象,所以直接添加下述代码解决该问题:
# views.py# 添加新主题@login_requireddef new_topic(request): if request.method != 'POST': form = TopicForm() else: # POST提交的数据,对数据进行处理 form = TopicForm(request.POST) if form.is_valid(): new_topic = form.save(commit=False) new_topic.owner = request.user new_topic.save() # form.save() return HttpResponseRedirect(reverse('learning_logs:topics')) context = {'form': form} return render(request, 'learning_logs/new_topic.html', context)
上一篇:锐捷云桌面怎么不连接服务器登录
下一篇:自己有的服务器怎么搭建?