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
答案 0 :(得分: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_set访问facility_set。