美文网首页Python学习日志python学习程序员
【day 16】python编程:从入门到实践学习笔记-基于Dj

【day 16】python编程:从入门到实践学习笔记-基于Dj

作者: 苍云横渡 | 来源:发表于2018-03-28 13:20 被阅读237次

    学习笔记目录
    【day 1】python编程:从入门到实践学习笔记-安装、变量和简单数据类型
    【day 2】python编程:从入门到实践学习笔记-列表以及其操作
    【day 3】python编程:从入门到实践学习笔记-if 语句(末附练习答案代码)
    【day 4】python编程:从入门到实践学习笔记-字典(末附练习答案代码)
    【day 5】python编程:从入门到实践学习笔记-用户输入和while循环(末附答案代码)
    【day 6】python编程:从入门到实践学习笔记-函数(末附练习答案代码)
    【day 7】python编程:从入门到实践学习笔记-类(末附练习答案代码)
    【day 8】python编程:从入门到实践学习笔记-文件和异常(末附练习答案代码)
    【day 9】python编程:从入门到实践学习笔记-测试代码(末附练习答案代码)
    【day 10】python编程:从入门到实践学习笔记-Django入门(一)
    【day 11】python编程:从入门到实践学习笔记-Django入门(二)
    【day 12】python编程:从入门到实践学习笔记-Django入门(三)
    【day 13】python编程:从入门到实践学习笔记-Django入门(四)
    【day 14】python编程:从入门到实践学习笔记-用户账户(一)
    【day 15】python编程:从入门到实践学习笔记-用户账户(二)
    【day 16】python编程:从入门到实践学习笔记-用户账户(三)
    【day 17】python编程:从入门到实践学习笔记-设计样式和部署(一)
    【day 18】python编程:从入门到实践学习笔记-设计样式和部署(二)& 补充

    第十九章 用户账户(三)

    让用户拥有自己的数据

    这部分我们将创建一个系统,确定各项数据所属的用户,再限制对页面的访问,让用户只能使用自己的数据。
    修改模型Topic,让每个主题都归属特定用户。

    使用@login_required限制访问

    装饰器是放在函数定义前面的指令,python在函数运行前,根据它来修改函数代码的行为。
    装饰器@login_required:让特定的页面只允许已登录的用户访问。
    1.限制对topics页面的访问
    修改learning_logs/views.py

    #--snip--
    from django.core.urlresolvers import reverse
    from django.contrib.auth.decorators import login_required
    
    from .models import Topic, Entry
    #--snip--
    
    @login_required
    def topics(request):
        #--snip--
    

    加上装饰器之后,python会在运行topics()的代码前先运行login_required()的代码。
    login_required()会检查用户是否已登录,仅当用户已登录时,django才运行topics()。如果用户未登录,则重定向到登录页面。
    为实现重定向,修改settings.py,在文件末尾加上 LOGIN_URL = '/users/login/' 。现在未登录的用户会重定向到 LOGIN_URL 指定的URL。
    2.全面限制对项目“学习笔记”的访问
    现在,我们不限制对主页、注册、注销页面的访问,而限制对其他所有页面的访问。
    在learning_logs/views.py中,除了index()意外,每个视图都加上 @login_required

    --snip--
    @login_required
    def topics(request):
        --snip--
    
    @login_required
    def topic(request, topic_id):
        --snip--
    
    @login_required
    def new_topic(request):
        --snip--
    
    @login_required
    def new_entry(request, topic_id):
        --snip--
    
    @login_required
    def edit_entry(request, entry_id):
        --snip--
    

    将数据关联到用户

    修改模型Topic,添加一个关联到用户的外键。然后必须对数据库进行迁移。最后对部分视图进行修改,使其只显示与当前用户登录的相关联的数据。
    1.修改模型Topic
    修改learning_logs/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--
    

    2.确定当前有哪些用户
    为了简单,我们将既有主题都关联到超级用户上,先确定超级用户的id,打开shell。

    确定当前用户只有admin,id为1。(或者还有其他你自己创建的用户)
    3.迁移数据库
    获取id之后,迁移数据库。 首先执行命令makemigrations后,django指出我们视图给既有模型Topic添加一个必不可少(不可为空)的字段(无默认值),并提供了两种选择:要么现在提供默认值,要么退出并在models.py中添加默认值。在这里我选了第一个选项,输入默认值,接着输入了用户id = 1。最后django使用这个值迁移数据库,在模型Topic中添加字段owner。
    接下来执行迁移,执行命令python manage.py migrate

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

    当前不管哪个用户登录,都能看到所有主题,现在我们让用户只能看到自己的主题。
    修改learning_logs/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属性,其存储了有关该用户的所有信息。filter()用于过滤序列,过滤掉不符合条件的元素,返回由符合条件元素组成的新列表。在这里我们用这个函数从数据库中只获取owner属性为当前用户的Topic对象。

    保护用户的主题

    在此之前,已登录的用户可输入URLhttp://127.0.0.1:8000/topics/1/来访问显示相应主题的页面。
    为修复这种问题,,我们在视图函数topic()获取请求的条目前执行检查。

    from django.shortcuts import render
    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)
        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。

    保护页面edit_entry

    接下来保护页面http://127.0.0.1:8000/edit_entry/1/。修改views.py

    #--snip--
    @login_required
    def 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':
    #--snip--
    

    将新主题关联到当前用户

    当前,添加新主题的页面没有将新主题关联到特定用户。修改views.py

    #--snip--
    @login_required
    def new_topic(request):
        if request.method != 'POST':
            form = TopicForm()
        else:
            form = TopicForm(request.POST)
            if form.is_valid():
                new_topic = form.save(commit=False)
                new_topic.owner = request.user
                new_topic.save()
                return HttpResponseRedirect(reverse('learning_logs:topics'))
    
        context = {'form': form}
        return render(request, 'learning_logs/new_topic.html', context)
    #--snip--
    

    首先调用form.save(commit=False)是为了先修改新主题,暂时不提交到数据库中。接下来将新主题的 owner属性设置为当前用户后,最后在保存提交到数据库中。

    现在这个项目允许任何人注册,而且每个用户可以添加任意数量的新主题。每个用户都只能访问自己的数据,无论是查看数据、输入新数据还是修改就数据都是如此。

    相关文章

      网友评论

        本文标题:【day 16】python编程:从入门到实践学习笔记-基于Dj

        本文链接:https://www.haomeiwen.com/subject/fsgscftx.html