0

Here is my models.py:

class Item(models.Model):
    # ... some irrelevent fields ...
    tags = models.ManyToManyField('Tag')

class Tag(models.Model):
    name = models.CharField(max_lenght=30)
    category_id = models.IntegerField()

Tag is actually a general-purpose name. Each item has many different type of tags - currently there are four types: team tags, subject tags, admin tags and special tags. eventually there will probably be a few more.

The idea is, they all have basically the same fields, so instead of having like 4 tables with manytomany relationship, and instead of adding a new column for Item whenever adding a new type, everything is called a 'tag' and it's very easy to add new types without any change to the schema.

Now to handle this in the admin.py I'm using dyamically created proxy models (based on this), as such:

def create_modeladmin(modeladmin, model, name = None):
    class  Meta:
        proxy = True
        app_label = model._meta.app_label

    attrs = {'__module__': '', 'Meta': Meta}

    newmodel = type(name, (model,), attrs)

    admin.site.register(newmodel, modeladmin)
    return modeladmin


class TagAdmin(models.Model):
    def queryset(self):
        return self.model.objects.filter(category_id = self.cid)

class TeamAdmin(TagAdmin):
    cid = 1

class SubjectAdmin(TagAdmin):
    cid = 2
# ... and so on ...

create_modeladmin(TeamAdmin, name='Teams', model=Tag)
create_modeladmin(SubjectAdmin, name='Subject', model=Tag)
#... and so on ...

This works great for me. However, different staff members need different editing permissions - one guy shouldn't access admin tags, while the other should only have access to edit subject-tags and team-tags. But as far as the admin site is concerned - the dynamic models do not exist in the permission list, and I can't give anyone permissions regarding them.

i.e. a user given all permissions on the list will still not have access to edit any of the dynamic models, and the only way to let anyone access them at all is to give him a superuser which obviously defies the point

I searched SO and the web and I can't anyone with a similar problem, and the docs don't say anything about this not in the dynamic models section or the proxy models section. so I'm guessing this is a different kind of problem. Any help would be greatly appreciated

UPDATE

So after some research into it, the answer was simple enough. Since permissions in django are objects that are saved to the database, what I needed to do was simple - add the relevent permissions (and create new ContentType objects as well) to the db, and then I could give people specific pemissions.

However, this raised a new question - is it a good convention to put the function that creates the permissions inside create_modeladmin as a find_or_create sort of function (that basically runs every time) or should it be used as an external script that I should run once every time I add a new dynamic model (sort of like how syncdb does it)?

And is there a way to also create the permissions dynamically (which seems to me like the ideal and most fitting solution)?

Community
  • 1
  • 1
yuvi
  • 18,155
  • 8
  • 56
  • 93
  • Also, looking at this: http://blog.muhuk.com/2009/05/14/django-permission-system.html#.UmBEJ1CGqNo I'm beginning to think of maybe creating my own Permission object than creating dynamic proxy models that point to it. Seems like a hack but might be the direction I'm looking for here – yuvi Oct 17 '13 at 20:13
  • similar to: http://stackoverflow.com/questions/8096980/user-permissions-on-proxy-models-in-modeladmin – fastmultiplication Dec 24 '13 at 09:22
  • I made a script to do this here: http://stackoverflow.com/questions/5486018/django-how-to-make-modeladmin-classes-show-up-in-available-permissions/20759563#20759563 – fastmultiplication Dec 24 '13 at 10:51
  • Thanks man, but as you can see the question is two months old. I have figured the answer out myself, and left it open in case someone suggested a dynamic solution that will not require to manually add the required permissions and/or contenttypes – yuvi Dec 24 '13 at 10:56

1 Answers1

-1

of course you can create permissions, django have django.contrib.auth.management.create_permissions to do this

Jerzyk
  • 3,662
  • 23
  • 40