5

Models:

Company

Product

We have a parent company (owner of all) who can create any Company and any Product, as sub-Company or sub-Product.

Now, what I'd like to accomplish, is limiting which Company can CRUD other Companies and Products alike.

Here's are the scenarios:

Company and Sub-Companies (sub-contractors):

Master (creates) -> Company “A”
Master (creates) -> Company “B” (creates) -> Company “C”
Master (creates) -> Company “D” (creates) -> Company “F” (creates) -> Company “G”

Company and Product Assignment:

Master (Add Product) -> Show all products
Master (assign products to top levels) -> Company “A”, Company “B” and Company ”D”

Sub-Company Product Assignment (management):

Company “B” (assign products only to sub-level) -> Company “C”
Company “D” (assign products only to sub-level) -> Company “F”
Company “F” (assign products only to sub-level) -> Company “G”

However, if Company D removes a product from a sub-level, this will also remove from all sub-level products recursively.

Are there any sure ways of doing this with Django core, or perhaps there's a recommended library out there that I'm not finding? I also saw in the Django docs reference to Model Meta options and the Options.permissions method... but I'm not sure that's what I'm needing either.

2
  • Permissions are generally related to (logged in) users. Does each user belong to a company?
    – Udi
    Commented Mar 13, 2017 at 10:37
  • Yes, each user belongs to a company.
    – dcolumbus
    Commented Mar 27, 2017 at 20:53

4 Answers 4

5
+25

The best package I can suggest you is DJANGO GUARDIAN. But what you are really looking for Role Based Access Control Logic.

Unfortunately django-guardian doesn't support roles. Linked issue. So I suggest you write your own views for that. But you can look into these below packages:

2
  • Thanks for this, do you know of any examples out there using Guardian that I could dissect?
    – dcolumbus
    Commented Mar 30, 2017 at 17:53
  • DOCS are always the best sources. But since you asked, check this SO question as well. Commented Mar 31, 2017 at 7:13
1
class Company(models.Model)
    parent = models.ForeignKey('self', blank=True, null=True, related_name='children')


Company.objects.get(pk=1).children.all()

The rest of the logic I can control through Views

1

There are a few general ways to manage access, including ownership/role and object specific permissions.

Ownership is what Django Organizations uses as the out-of-the-box permission management strategy. An object is owned by an organization - and only one - and access is limited to members (role) of that organization. You can expand on this as you like in a Django Organizations-based application, but you don't most of the benefits.

Instead, it sounds like you need a hierarchal solution to manage access to objects (companies or products) that do not necessarily have a primary relationship to one specific company. That is, an admin at the top level may choose to associate a product with one or more child companies, and removing an association would recursively remove that object's associations further down the tree.

So it does sound like you should take a look at either django-mptt or django-treebeard to record a tree of the company and product relationships, using the tree as the source of truth for access in views, and ensuring that all child relationships are removed when a product is removed from one company.

I'd stress that this sounds like part because it's not totally clear if that is exactly what you're trying to solve for and if that's all that you need to solve for.

1
  • Also, are you suggesting that django-mptt would be used in conjunction with django-organizations?
    – dcolumbus
    Commented Apr 25, 2017 at 16:19
0

Use a base view that checks which company the user belongs to. Each (inherited) view will restrict the functionality depending on the logged in user's company. Use django-mptt for dealing with tree structured data.

Not the answer you're looking for? Browse other questions tagged or ask your own question.