【问题标题】:Make models belong to users in django在 django 中使模型属于用户
【发布时间】:2014-02-19 04:54:41
【问题描述】:

我正在使用 django.contrib.auth,我想知道如何使模型的实例“属于”特定用户。我是否需要在模型中定义指向用户的外键?我希望用户自己保留他们的 CRUD。

# The objects created from this model should belong 
# to the user who created them and should not be 
# viewable by other users of the website.

from django.contrib.auth.models import User

class Classroom(models.Model):
    user = models.ForeignKey(User)
    name = models.CharField(max_length=30)
    def __unicode__ (self):
        return self.name

谢谢。

【问题讨论】:

  • 一个模型还是一个模型实例?模型相当于表,模型实例相当于行。请澄清您的要求。
  • “从此模型创建的对象” => 实例,对吗?

标签: python django authentication


【解决方案1】:

这是我采取的一般方法:

创建属于用户的模型

  1. 在模型上,为用户提供外键。
  2. 定义一个需要将用户传递给构造函数的自定义 ModelForm (__init__())。此外,覆盖表单的 save() 方法,以便在保存之前将传递给构造函数的用户添加到模型实例中。
  3. 基于CreateView 等定义基于类的视图,覆盖get_form_kwargs 方法以传递用户存储在请求中的表单。

代码如下:

# models.py

from django.db import models
from django.contrib.auth.models import User


class MyModel(models.Model):
    "A model that belongs to a user."

    user = models.ForeignKey(User)

# forms.py

from django import forms
from .models import MyModel

class MyModelForm(forms.ModelForm):
    """A form for creating/updating MyModels that accepts
    the user as a kwarg.
    """

    def __init__(self, *args, **kwargs):
        self.user = kwargs.pop('user')
        super(MyModelForm, self).__init__(*args, **kwargs)

    def save(self, *args, **kwargs):
        self.instance.user = self.user
        return super(MyModelForm, self).save(*args, **kwargs)

    class Meta:
        model = MyModel
        # Don't show the user on the form
        exclude = ('user',)

# views.py

from django.views.generic import CreateView
from .models import MyModel
from .forms import MyModelForm


class MyModelCreateView(CreateView):
    "View for creating a MyModel belonging to the current user."
    model = MyModel
    form_class = MyModelForm

    def get_form_kwargs(self, *args, **kwargs):
        form_kwargs = super(MyModelCreateView,
                        self).get_form_kwargs(*args, **kwargs)
        # Pass the current user to the form constructor
        form_kwargs['user'] = self.request.user
        return form_kwargs

列出属于用户的模型

这更直接 - 您扩展 ListView 并过滤当前用户的查询集。 (Read more about ListView.)

编辑属于用户的模型

使用与MyModelCreateView 类似的方法,但改为扩展UpdateView。这里重要的是检查用户是否有编辑权限:

# views.py
from django.views.generic import UpdateView
from django.core.exceptions import PermissionDenied
...

class MyModelUpdateView(UpdateView):
    "View for the current user editing a MyModel."""

    model = MyModel
    form_class = MyModelForm

    def get_object(self, *args, **kwargs):
        object = super(MyModelUpdateView, self).get_object(*args, **kwargs)
        # Raise a permission denied if the current user doesn't
        # 'own' the MyModel they're trying to edit.
        if object.user != self.request.user:
             raise PermissionDenied

    def get_form_kwargs(self, *args, **kwargs):
        form_kwargs = super(MyModelCreateView,
                    self).get_form_kwargs(*args, **kwargs)
        # Pass the current user to the form constructor
        form_kwargs['user'] = self.request.user
        return form_kwargs

【讨论】:

    【解决方案2】:

    如果您想让多个对象属于该用户,则用户对象的foreign key field 将起作用。请注意,您仍然可以使用外键,并通过传递 字段定义的unique 属性。


    如果一个对象(并且只有一个)属于用户,请使用one to one field。可以从模型的任一侧访问一对一的字段

    您可以使用user.classroomclassroom.user,这些绑定可以通过一对一字段定义的related_name 属性进行更改。

    【讨论】:

    • 那么,在视图中查找属于用户的对象就足以防止用户看错对象了吗?
    • @broinjc 不,你需要自己处理。
    • @BurhanKhalid 那我该如何处理呢?
    • @broinjc 在视图中处理类似if classroom.user == request.user:...
    • 在课堂创建表单中,我会隐藏用户外键字段并自动填写当前用户?
    猜你喜欢
    • 2014-03-30
    • 1970-01-01
    • 2019-11-03
    • 2012-07-20
    • 1970-01-01
    • 1970-01-01
    • 2011-09-05
    • 2020-02-12
    • 1970-01-01
    相关资源
    最近更新 更多