Hello,
I have a multilingual Django project. Every language is a different subdomain. So we've decided to use the "sites" application and to create one different site for every language.
On that project, I also have a "pages" application, which is quite similar to a CMS. The user can create pages with content and they'll be displayed in the appropriate language site.
Now I'm looking to be able to manage advanced permissions. What I need to do is to allow, in the admin application a user only to create and update pages for one (or many) specific language/site.
What'd be the cleaner way to do something like that ?
Edit : Here is the solution I've adapted, given by Chris
I create a decorator that's checking if the user is appropriately in the group that has access to the lang. See Chris' accepted answer for an example of this.
In a "normal" view, I do the following :
def view(self):
# Whatever you wanna do
return render_to_response('page.html', {}, RequestContext(request))
view = group_required(view)
If the user is in the group, it'll return the method. Otherwise, it'll return an "Access Denied" error.
And in my admin, I do the following :
class PageAdmin(admin.ModelAdmin):
list_display = ('title', 'published')
fieldsets = [
(None, {'fields': ['title', 'slug', 'whatever_field_you_have']}),
]
def has_add_permission(self, request):
return in_group_required(request)
admin.site.register(Page, PageAdmin)
Where the in_group_required is a similar method to group_required mentionned above. But will return only true or false depending of if we have access or not.
And because we use them quite much in the previous examples, you'll find above here what I have in my in_group and group_required methods.
def group_required(func):
def _decorator(request, *args, **kwargs):
if not in_group(request):
return HttpResponse("Access denied")
return func(*args, **kwargs)
return _decorator
def in_group(request):
language = Language.objects.get(site__domain__exact=request.get_host())
for group in language.group.all():
if request.user in group.user_set.all():
return True
return False