首页 > 解决方案 > 在 django-generic-views 中隐藏某些用户的用户数据

问题描述

我的目标是允许用户使用嵌套的 Task 实例创建自己的 Project 实例。其他用户不应有权访问不是他们创建的数据。我怎样才能正确地做到这一点?我为 编写了一个自定义查询集ProjectListView,但其他视图有问题。也许这种情况有一个通用的解决方案?

模型.py

class Project(models.Model):
    project_name = models.CharField(max_length=150, default='')
    user = models.ForeignKey(get_user_model(), null=True, on_delete=models.CASCADE)

class Task(models.Model):
    project = models.ForeignKey(Project, on_delete=models.CASCADE)
    task_name = models.CharField(max_length=250, default='')
    is_done = models.BooleanField(default=False)

视图.py

class ProjectListView(LoginRequiredMixin, ListView):
    model = Project
    context_object_name = 'projects'

    def get_queryset(self):
        return Project.objects.filter(user=self.request.user)

class ProjectCreateView(LoginRequiredMixin, CreateView):
    model = Project
    fields = ('project_name',)
    success_url = reverse_lazy('projects')

class ProjectUpdateView(LoginRequiredMixin, UpdateView):
    model = Project
    fields = ('project_name',)
    template_name = 'backend/project_update_form.html'
    success_url = reverse_lazy('projects')

class ProjectDeleteView(LoginRequiredMixin, DeleteView):
    model = Project
    success_url = reverse_lazy('projects')

class TaskCreateView(LoginRequiredMixin, CreateView):
    model = Task
    fields = '__all__'
    success_url = reverse_lazy('projects')

class TaskUpdateView(LoginRequiredMixin, UpdateView):
    model = Task
    fields = ('task_name', 'is_done',)
    template_name = 'backend/task_update_form.html'
    success_url = reverse_lazy('projects')

class TaskDeleteView(LoginRequiredMixin, DeleteView):
    model = Task
    success_url = reverse_lazy('projects')

结果:

class TaskCreateView(LoginRequiredMixin, TaskMixin, CreateView):
    model = Task
    fields = '__all__'
    success_url = reverse_lazy('projects')

    def get_form(self, *args, **kwargs):
        form_class = super().get_form(form_class=None)

        form_class.fields['project'].choices =\
            [(project.pk, project) for project in Project.objects.filter(user=self.request.user)]
        
        return form_class

标签: djangodjango-viewsdjango-generic-views

解决方案


您可以将该自定义查询集移动到mixin

# mixins.py
class ProjectMixin(object):
    def get_queryset(self):
        return Project.objects.filter(user=self.request.user)

class TaskMixin(object):
    def get_queryset(self):
        return Task.objects.filter(project__user=self.request.user)

# views.py
class ProjectListView(LoginRequiredMixin, ProjectMixin, ListView):
    model = Project
    context_object_name = 'projects'

class ProjectCreateView(LoginRequiredMixin, ProjectMixin, CreateView):
    model = Project
    fields = ('project_name',)
    success_url = reverse_lazy('projects')

class ProjectUpdateView(LoginRequiredMixin, ProjectMixin, UpdateView):
    model = Project
    fields = ('project_name',)
    template_name = 'backend/project_update_form.html'
    success_url = reverse_lazy('projects')

class ProjectDeleteView(LoginRequiredMixin, ProjectMixin, DeleteView):
    model = Project
    success_url = reverse_lazy('projects')

class TaskCreateView(LoginRequiredMixin, TaskMixin, CreateView):
    model = Task
    fields = '__all__'
    success_url = reverse_lazy('projects')

class TaskUpdateView(LoginRequiredMixin, TaskMixin, UpdateView):
    model = Task
    fields = ('task_name', 'is_done',)
    template_name = 'backend/task_update_form.html'
    success_url = reverse_lazy('projects')

class TaskDeleteView(LoginRequiredMixin, TaskMixin, DeleteView):
    model = Task
    success_url = reverse_lazy('projects')

推荐阅读