如何限制除当前用户之外的其他用户访问Django数据库中的数据

113 阅读2分钟

在一个Django项目中,需要在不同用户之间隔离数据,即每个用户只能访问自己的数据,而不能访问其他用户的数据。但是,在现有的代码中,所有用户的项目和承包商数据都是共享的,任何一个用户注册后都可以看到所有其他用户的项目和承包商。

2、解决方案

为了解决这个问题,需要在数据库中为每个用户单独创建项目和承包商表,并在视图中添加必要的过滤条件,以确保每个用户只能访问自己的数据。

1. 修改模型

在模型中,需要修改Project模型,将client字段从OneToOneField改为ForeignKey,并添加一个user字段,以存储项目的创建者。还需要修改Contractor模型,添加一个user字段,以存储承包商的创建者。

class Contractor(models.Model):
   name=models.CharField(max_length=128)
   url=models.URLField()
   bill_rate=models.IntegerField(default=0)
   user=models.ForeignKey(User, on_delete=models.CASCADE)
   slug=models.SlugField(unique=True)

   def save(self, *args, **kwargs):
      self.slug=slugify(self.name)
      super(Contractor, self).save(*args, **kwargs)
   def __unicode__(self):
      return self.name

class Project(models.Model):
    contractor=models.ManyToManyField(Contractor)
    client=models.ForeignKey(UserProfile, on_delete=models.CASCADE, null=True)
    user=models.ForeignKey(User, on_delete=models.CASCADE)
    title=models.CharField(max_length=128)
    slug=models.SlugField(unique=True)
    contractor_hours=models.IntegerField(default=0)

    def save(self, *args, **kwargs):
       self.slug=slugify(self.title)
       super(Project, self).save(*args, **kwargs)

    def __unicode__(self):
       return self.title

2. 修改视图

在视图中,需要修改dashboard视图,在查询项目和承包商数据时,添加user字段的过滤条件,以确保只查询出当前用户的项目和承包商数据。

def dashboard(request):
      context_dict={}
      project_list=Project.objects.filter(user=request.user).order_by('-title')
      contractor_list=Contractor.objects.filter(user=request.user).order_by('-name')
      context_dict['Projects']=project_list
      context_dict['Contractors']=contractor_list
     return render(request, 'keeper/dashboard.html', context_dict)

代码例子

from django.contrib.auth.models import User
from django.db import models
from django.db.models import CASCADE
from django.urls import reverse
from django.utils.text import slugify

class Contractor(models.Model):
   name=models.CharField(max_length=128)
   url=models.URLField()
   bill_rate=models.IntegerField(default=0)
   user=models.ForeignKey(User, on_delete=CASCADE)
   slug=models.SlugField(unique=True)

   def save(self, *args, **kwargs):
      self.slug=slugify(self.name)
      super(Contractor, self).save(*args, **kwargs)
   def __unicode__(self):
      return self.name

class Project(models.Model):
    contractor=models.ManyToManyField(Contractor)
    client=models.ForeignKey(UserProfile, on_delete=CASCADE, null=True)
    user=models.ForeignKey(User, on_delete=CASCADE)
    title=models.CharField(max_length=128)
    slug=models.SlugField(unique=True)
    contractor_hours=models.IntegerField(default=0)

    def save(self, *args, **kwargs):
       self.slug=slugify(self.title)
       super(Project, self).save(*args, **kwargs)

    def __unicode__(self):
       return self.title


def dashboard(request):
      context_dict={}
      project_list=Project.objects.filter(user=request.user).order_by('-title')
      contractor_list=Contractor.objects.filter(user=request.user).order_by('-name')
      context_dict['Projects']=project_list
      context_dict['Contractors']=contractor_list
     return render(request, 'keeper/dashboard.html', context_dict)