让用户拥有自己的数据

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

使用@login_required限制访问

@login_required
#--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--
topics()login_required()login_required()topics()LOGIN_URL = '/users/login/'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之后,迁移数据库。



makemigrationspython 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对象。

保护用户的主题

http://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/
#--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属性设置为当前用户后,最后在保存提交到数据库中。

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