Django项目——让用户拥有自己的数据

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/chengqiuming/article/details/84886288

一 使用 @login_required  限制访问

1 限制对 topics 页面的访问

learning_logs/views.py代码修改如下:

'''
login_required() 的代码检查用户是否已登录,仅当用户已登录时, Django 才运行 topics() 的代码。
如果用户未登录,就重定向到登录页面。
'''
@login_required
def topics(request):
    '''
    用户登录后, request 对象将有一个 user 属性,这个属性存储了有关该用户的信息。
    代码 Topic.objects.filter(owner=request.user) 让 Django 只从数据库中获
    取 owner 属性为当前用户的 Topic 对象。
    '''
    topics = Topic.objects.filter(owner=request.user).order_by('date_added')
    context = {'topics': topics}
    return render(request, 'learning_logs/topics.html', context)

2 settings.py中增加如下内容:

# 让 Django 知道到哪里去查找登录页面。
# 如果未登录的用户请求装饰器 @login_required 的保护页面,
# Django 将重定向到 settings.py 中的 LOGIN_URL 指定的 URL
LOGIN_URL = '/users/login/'

二 将数据关联到用户

1 修改模型Topic

# -*- coding: utf-8 -*-
from django.db import models
# 导入了 django.contrib.auth 中的模型 User
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)
    # 在 Topic 中添加了字段 owner ,它建立到模型 User 的外键关系。
    owner = models.ForeignKey(User)

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

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

在 views.py 中,对函数 topics() 做如下修改:
'''
login_required() 的代码检查用户是否已登录,仅当用户已登录时, Django 才运行 topics() 的代码。
如果用户未登录,就重定向到登录页面。
'''
@login_required
def topics(request):
    '''
    用户登录后, request 对象将有一个 user 属性,这个属性存储了有关该用户的信息。
    代码 Topic.objects.filter(owner=request.user) 让 Django 只从数据库中获
    取 owner 属性为当前用户的 Topic 对象。
    '''
    topics = Topic.objects.filter(owner=request.user).order_by('date_added')
    context = {'topics': topics}
    return render(request, 'learning_logs/topics.html', context)

四 保护用户的主题

1 修改views.py

@login_required
def topic(request, topic_id):
    #  显示单个主题及其所有的条目
    topic = Topic.objects.get(id=topic_id)
    #  确认请求的主题属于当前用户.收到主题请求后,在渲染网页前检查该主题是否属于当前登录的用户。
    # 如果请求的主题不归当前用户所有,我们就引发 Http404 异常,让 Django 返回一个 404 错误页面。
    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)

五 保护页面 edit_entry

'''
页面 edit_entry 收到 GET 请求时, edit_entry() 将返回一个表单,让用户能够对条目进行编辑。
页面收到 POST 请求(条目文本经过修订)时,它将修改后的文本保存到数据库中
'''
@login_required
def edit_entry(request, entry_id):
    """ 我们获取用户要修改的条目对象,以及与该条目相关联的主题。在请求方法为 GET 时将执行的 if 代码块中,我们使用实
        参 instance=entry 创建一个 EntryForm 实例。
        这个实参让 Django 创建一个表单,并使用既有条目对象中的信息填充它。用户将看到既有的数据,并能够编辑它们。
        处理 POST 请求时,我们传递实参 instance=entry 和 data=request.POST ,让 Django 根据既有条目对象创建一个表单实例,
        并根据 request.POST 中的相关数据对其进行修改。然后,我们检查表单是否有效,如果有效,就调用 save() ,且不指定任何实参。
        接下来,我们重定向到显示条目所属主题的页面,用户将在其中看到其编辑的条目的新版本。"""
    entry = Entry.objects.get(id=entry_id)
    topic = entry.topic
    # 然后检查主题的所有者是否是当前登录的用户,如果不是,就引发 Http404 异常。
    if topic.owner != request.user:
        raise Http404
    
    if request.method != 'POST':
        # 初次请求,使用当前条目填充表单
        form = EntryForm(instance=entry)
    else:
        # POST 提交的数据,对数据进行处理
        form = EntryForm(instance=entry, data=request.POST)
        if form.is_valid():
            form.save()
            return HttpResponseRedirect(reverse('learning_logs:topic',
                                        args=[topic.id]))
    
    context = {'entry': entry, 'topic': topic, 'form': form}
    return render(request, 'learning_logs/edit_entry.html', context)

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

@login_required
def new_topic(request):
    """ 添加新主题 """
    if request.method != 'POST':
        # 未提交数据:创建一个新表单
        form = TopicForm()
    else:
        # POST 提交的数据 , 对数据进行处理
        # HttpResponseRedirect 类,用户提交主题后我们将使用这个类将用户重定向到网页 topics 。
        # 函数 reverse() 根据指定的 URL 模型确定 URL ,这意味着 Django将在页面被请求时生成 URL 。
        # 我们还导入了刚才创建的表单 TopicForm 。
        # 我们使用用户输入的数据(它们存储在 request.POST 中)创建一个 TopicForm 实例
        # 这样对象 form 将包含用户提交的信息。
        form = TopicForm(request.POST)
        # 函数 is_valid() 核实用户填写了所有必不可少的字段(表单字段默认都是必不可少的),
        # 且输入的数据与要求的字段类型一致(例如,字段 text 少于 200 个字符)。
        # 这种自动验证避免了我们去做大量的工作。
        if form.is_valid():
            # 首先调用 form.save() ,并传递实参 commit=False ,
            # 这是因为我们先修改新主题,再将其保存到数据库中
            new_topic = form.save(commit=False)
            new_topic.owner = request.user
            # 将表单中的数据写入数据库
            new_topic.save()
            # 使用 reverse() 获取页面 topics 的 URL ,并将其传递给 HttpResponseRedirect()
            # 后者将用户的浏览器重定向到页面 topics 。
            # 在页面 topics 中,用户将在主题列表中看到他刚输入的主题。
            return HttpResponseRedirect(reverse('learning_logs:topics'))

    context = {'form': form}
    return render(request, 'learning_logs/new_topic.html', context)

七 测试

用户1的主题

用户2的主题

猜你喜欢

转载自blog.csdn.net/chengqiuming/article/details/84886288