Django how to define permissions so users can only edit certain model hierarchies?
<p>If I have models like this..</p>

<pre><code>class Family(Model):
    name = models.CharField()

class Father(Model):
    family = ForeignKey(Family)

class Mother(Model):
    family = ForeignKey(Family)

class Child(Model):
    family = ForeignKey(Family)
</code></pre>

<p>Django makes group permissions automatically so I can define groups that can edit/create/etc... the family model.</p>

<p>How can I limit it to only let a user edit a certain instance of the family model? So if I want the 'Johnson' family admin to only have permission to edit things under the 'Johnson' family tree. </p>

<p>I can think of two ways, one would be defining a custom permission like (<a href="https://docs.djangoproject.com/en/1.10/topics/auth/customizing/#custom-permissions" rel="nofollow">https://docs.djangoproject.com/en/1.10/topics/auth/customizing/#custom-permissions</a>) but I have no idea what the docs are saying there and they do not do a good job of explaining it. </p>

<p>I can also think of possibly adding a field on the user model and checking the value of that, but it feels wrong to do it that way...</p>

<p>I can imagine two ways for achieving what you want, but that'd be experimental and I don't know if it would follow the good practices :</p>

<h2>1 - <a href="https://docs.djangoproject.com/en/1.10/topics/auth/default/#programmatically-creating-permissions" rel="nofollow">Programmatically created permissions</a> :</h2>

<p>With codename partially based on the instance.
For example, creating a permission with a codename containing the instance the user could edit :</p>

<pre><code>perm = Permission.objects.create(codename='can_create_'+str(obj.id),
                                 name='can edit instance with id ' + str(obj.id))
user.user_permissions.add(perm)
</code></pre>

<p>and then :</p>

<pre><code>if user.has_perm('can_create_' + str(relevant_id)):
</code></pre>

<h2>2 - <a href="https://docs.djangoproject.com/en/1.10/ref/models/fields/#manytomanyfield" rel="nofollow">ManyToMany relationships as permissions</a> :</h2>

<p>Probably the field idea you had yourself :</p>

<pre><code>class myModel(models.Model):
    editors = models.ManyToManyField(User, related_name='mymodel_can_edit')
</code></pre>

<p>and then just add and remove the instances a user can delete in its <code>mymodel_can_edit</code> field just like you manage the permissions in its <code>user_permissions</code> field.</p>

<p>But I didn't test any of these solution.
If you try it could you tell what you think about it? :)</p>

python django