0
class Facilites(models.Model):
    id = models.CharField(max_length=32, primary_key=True)
    name = models.CharField(max_length=128)

class Objects(models.Model):
    name = models.CharField(max_length=64)
    facilityid = models.ForeignKey(Facilities)

class Admins(models.Model):
    user = models.OneToOneField(User)
    facilities = models.ManyToManyField(Facilities)

def create_user_profile(sender, instance, created, **kwargs):
    if created:
        Admins.objects.create(user=instance)

post_save.connect(create_user_profile, sender=User)

我想要的是让用户(管理员)只能将对象中的“facilityid”添加或修改为在他们的 Admins.facilities 中指定的值。因此,如果某个用户名为 UserA 并且有设施 = ('FacA', 'FacB'),当他向 DB 添加一个新对象时,他应该无法添加类似 Object('Random object', 'FacC ')

此外,他不应该能够将现有对象修改为他不属于的设施。

我已经过滤了对象:

def queryset(self, request):
    qs = super(ObjectsAdmin, self).queryset(request)
    if request.user.is_superuser:
        return qs
    return qs.filter(facitityid__id__in = request.user.get_profile().facilities.all())

所以用户只能看到属于他们设施的对象。但我不知道如何防止他们从他们的设施中添加/编辑对象。

编辑:

在这里找到答案:https ://stackoverflow.com/a/3048563/1421572

事实证明 ModelAdmin.formfield_for_foreignkey 在这种情况下是正确的答案:http: //docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.formfield_for_foreignkey

4

1 回答 1

2

我将使用预制的设施列表来执行此操作(即,您可以创建一个与 FACILITY_CHOICES 挂钩的整数字段供用户选择。)

如果只有管理员可以做到,那么权限听起来很可行。您还可以进行表单验证以检查数据库中的错误。根据您拥有的设施数量,您可能需要不同的方法。

您也可以使用 models.CharField 执行相同的技术。因此,也许为每个设施分配一个 3 个字母的设施代码,并要求条目与 3 个字母字符串之一匹配。您甚至可以在 .txt 文件中读取列表。真的有很多方法可以做到这一点。我将提供一个预制设施列表的示例,并从 api / 模板访问特定用户所属的设施:

NYC_FACILITY = 0
LA_FACILITY = 1
ATL_FACILITY = 2

FACILITY_CHOICES = (
    (NYC_FACILITY, 'NYC'),
    (LA_FACILITY, 'LA'),
    (ATL_FACILITY, 'ATL'),

class Facility(models.Model):
    name = models.IntegerField(choices=FACILITY_CHOICES, default="NYC")

    class Meta:
        order_by = ['name']
        verbose_name_plural = "facilities"
        verbose_name = "facility"
    def __unicode__(self):
        return self.name

就查看特定用户所属的设施页面而言,对象之间将具有 m2m 一对一或 FK 关系。如果 FK 或 m2m 关系,那么您将可以访问该模型类型的其他方法。get_related 但是,我不会在我的示例中使用 get_related。一旦你在一个实例中,你就可以访问 entry_set。

# models.py
from django.auth import User
class Person(User):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    facility_loc = models.ForeignKey('Facility') # ForeignKey used assuming only one person can belong to a facility.
    slug = models.SlugField(unique=True)

def get_absolute_url(self):
    return "/%s/%s/" % self.facility_loc % self.slug

# views.py - TemplateView is automatically given a context variable called params which parses data from the URL. So, I'll leave the regex in the URLConf up to you.

class UserFacilityView(TemplateView):
    model = Facility
    template_name = "user_facility.html"

现在在您的模板中,您应该能够从 User 实例访问 facility_set 或从设施实例访问 user_set。

于 2012-05-28T12:21:40.917 回答