-
-
Notifications
You must be signed in to change notification settings - Fork 50
Two roles with admin in project #28
Comments
OK. Let say there is an class Article(models.Model):
title = models.CharField(...)
body = models.TextField(...)
author = models.ForeignKey(User, ...)
published = models.BooleanField(...) And you want to 1) add, 2) change, 3) delete, 4) publish the news article. So you need the following permissions.
Then, use the followings to do what you want Like: class Article(models.Model):
...
from permission import add_permission_logic
from permission.logics import AuthorPermissionLogic, StaffPermissionLogic
add_permission_logic(Article, AuthorPermissionLogic(
field_name='author',
any_permission=False,
change_permission=True,
delete_permission=True,
))
add_permission_logic(Article, StaffPermissionLogic(
any_permission=False,
change_permission=True,
delete_permission=True,
)) Then use @permission_required('news.add_article') # It might no be required if anyone can create the article
class ArticleCreateView(CreateView):
# staff and users (may be everybody?) should have 'news.add_article' permission
...
@permission_required('news.change_article')
class ArticleUpdateView(UpdateView):
# the permission is handled either AuthorPermissionLogic or StaffPermissionLogic
...
@permission_required('news.delete_article')
class ArticleDeleteView(DeleteView):
# the permission is handled either AuthorPermissionLogic or StaffPermissionLogic
...
@permission_required('news.publishe_aritcle')
class ArticlePublishView(View):
# staff users should have 'news.publish_article' permission
# in the post method, change the 'published' attribute of the specified article
.... Finally, give |
But, i have a model author how a OnetoOneField with User, you know, custom user, but, i want that default admin user and Author User don't be the same. And i want that the autor only can edit and delete his own news, no other author's news. And i don't want create another views, i want use the default admin system for all users. And, your apps will integrated with de default admin system? |
I'm sorry but I'm a bit confuse with this sentence. What were you trying to say exactly?
Check the source code of
Then read the django's document. https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.has_add_permission class ArticleAdmin(Admin):
def has_change_permission(self, request, obj=None):
return request.has_perm('news.change_article', obj) However, similar codes were written in default method. https://github.com/django/django/blob/master/django/contrib/admin/options.py#L465 Thus what you need to do is basically nothing.
django-permission will extend the default authentication system (django.contrib.auth) but default admin system (django.contrib.admin). |
https://help.github.com/articles/markdown-basics You are using Extending the existing user model strategy right? Then several codes are not necessary. class Author(models.Model):
user = models.OneToOneField(User)
biography = models.TextField(verbose_name='BiografÃa', blank=True)
age = models.PositiveIntegerField(verbose_name='Edad', blank=True )
link_own = models.URLField(verbose_name='Enlace Propio', blank=True)
# `is_superuser` is provided in auth.User,
is_superuser = False
# `auth.User.is_staff` can be used instaed of `can_publish`
can_publish = False
class Meta:
ordering=['last_name']
verbose_name = 'Autor'
verbose_name_plural='Autores'
permissions = {
}
def __str__(self):
return '%s %s' % (self.first_name,self.last_name) Ok. I'm guessing but you create So there are two options. The first one is re-consider about your current strategy and follow the general strategy.
This is quite common way so if you chose this strategy, django-permissin (and other plugins which use authentication system) works without patient. If somehow you have to use the strategy, you should write your special permission logic like the below. Remember that django-permission is powerful enough to do this kind of hackish things but most of other plugins won't, mean that you might face to other problems in the future. class SpecialPermissionLogic(PermissinoLogic):
def has_perm(self, user_obj, perm, obj=None):
if not user_obj.is_authenticated():
return False
add_permission = self.get_full_permission_string('add')
change_permission = self.get_full_permission_string('change')
delete_permission = self.get_full_permission_string('delete')
publish_permission = self.get_full_permission_string('publish')
try:
author = Author.objects.get(user=user_obj)
if obj is None:
# Non object permission. Author should have add/change/delete
# but publish
if author.is_superuser:
# Admin user should have publish permission as well, mean
# Admin user have all permissions
return True
else:
return perm in (add_permission,
change_permission,
delete_permission)
else:
# Object permission
if obj.author == user_obj:
# Author of the object should have change/delete
return perm in (change_permission, delete_permission)
return False
except ObjectDoesNotExist:
return False |
Well, i don't speak english very good, but step by step i understand you. First, i need the author user can other fields, can you see in my model, is very important. If i understand you, my model is very useful, but I must not use my model to set the permissions, right? My news model is this: news.models.py from django.db import models
from django.template.defaultfilters import slugify
from django.core.urlresolvers import reverse
from authors.models import Author
from subtopic.models import Subtopic
from topic.models import Topic
from keywords.models import KeyWord
#Global Vars
# Create your models here.
class New(models.Model):
title = models.CharField(verbose_name='Título', max_length=255, unique=True)
topic = models.ForeignKey(Topic, verbose_name='Tema', related_name='news', )
subtopic = models.ForeignKey(Subtopic, verbose_name='Subtema', related_name='news') #Filtramos por Opinion para sacar todas las columnas
author = models.ForeignKey(Author, verbose_name='Autor', related_name='news')
keywords = models.ManyToManyField(KeyWord, blank=True, verbose_name='Palabras Clave', related_name='news')
created_date = models.DateTimeField(auto_now_add=True, verbose_name='Fecha y Hora')
place = models.CharField(max_length=255, verbose_name='Lugar')
content = models.TextField(verbose_name='Contenido')
source = models.URLField(verbose_name='Fuente', blank=True)
slug = models.SlugField(verbose_name='Slug', max_length=100, unique=True)
is_published = models.BooleanField(verbose_name='Publicada', default=False,) #Nueva, para verificar si se publica o no
times_viewed = models.PositiveIntegerField(default=0, editable=False, verbose_name='Veces Vista' )
class Meta:
ordering=['-created_date']
verbose_name_plural='Noticias'
#@models.permalink
#def get_absolute_url(self):
# return ('news.views.New_view', None, {'year': self.dateTime.year,
# 'month': self.dateTime.strftime('%m'),
# 'day': self.dateTime.strftime('%d'),
# 'slug': self.slug})
def first_image(self):
return self.images.first() # Siendo images el related_name en Image
def first_video(self):
return self.video.first()
def get_absolute_url(self):
return reverse ('NewsDefaultView', args = [str(self.created_date.strftime("%Y")), str(self.created_date.strftime("%m")), str(self.created_date.strftime("%d")), str(self.slug)])
def get_all_keys(self):
keys_list = self.keywords.values_list('name', flat=True)
return str(keys_list).strip("'[]'").replace("'",'')
#def is_published(self): devuelve si la noticia ha sido pulicada para que salga en la lista de noticias
def __str__(self):
return self.title
def save(self): #Definir metodo para guardar, validar y otros metodos del Slug
super(New, self).save() #Solo con este me funciona correctamente
if not self.id:
self.slug = slugify(self.title)
super(New, self).save()
from django.core.cache import cache
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.contrib.sessions.models import Session
@receiver(post_save)
def clear_cache(sender, **kwargs):
if sender != Session:
cache.clear() |
Then I would like to create Remember that there should be only one model which represent Users in your project. In your case, there are two models ( |
I have to do a custom User Model for my Author?
I don't understand this, i need create other model user for Author? ca't be auth.User.Author? author = models.ForeignKey(User, verbose_name='Autor', related_name='news') In my news model write this, right? Then my author model have to be so: class Author(models.Model):
#Campos del Usuario
photo = models.ImageField(verbose_name = 'Profile photo', blank = True, null=True)
user = models.OneToOneField(User)
biography = models.TextField(verbose_name='Biografía', blank=True, null=True)
age = models.PositiveIntegerField(verbose_name='Edad', blank=True, null=True )
link_own = models.URLField(verbose_name='Enlace Propio', blank=True, null=True)
class Meta:
ordering=['last_name']
verbose_name = 'Autor'
verbose_name_plural='Autores'
def __str__(self):
return '%s %s' % (self.first_name,self.last_name)
def photo_display(self):
if self.photo:
return '<img src="%s" alt="%s" title="%s">' % (get_thumbnail(self.photo, '100x100').url, self.first_name, self.first_name)
else:
return '/statics/static/tiempo_turco/images/no-profile.png' right? |
Basically no but probably yes in your case while you are trying to use your def view(request, *args, **kwargs):
if request.user.is_authenticated():
# do thins for authenticated user
else:
# do thins for anonymous user This is a general idea of django so most of django app, including django-permission, follow this rule.
I said
but your
Your model should be following if you don't use custom user model strategy. class Author(models.Model):
#Campos del Usuario
photo = models.ImageField(verbose_name = 'Profile photo', blank = True, null=True)
# user = models.OneToOneField(User)
# primary_key=True should be specified
user = models.OneToOneField(User, primary_key=True)
biography = models.TextField(verbose_name='Biografía', blank=True, null=True)
age = models.PositiveIntegerField(verbose_name='Edad', blank=True, null=True )
link_own = models.URLField(verbose_name='Enlace Propio', blank=True, null=True)
class Meta:
ordering=['last_name']
verbose_name = 'Autor'
verbose_name_plural='Autores'
def __str__(self):
# return '%s %s' % (self.first_name,self.last_name)
# the line above should be ...
return '%s %s' % (self.user.first_name,self.user.last_name)
def photo_display(self):
if self.photo:
# you should use `self.user.first_name`
return '<img src="%s" alt="%s" title="%s">' % (get_thumbnail(self.photo, '100x100').url, self.first_name, self.first_name)
else:
return '/statics/static/tiempo_turco/images/no-profile.png' |
Ok make it simple. I have a simple advice. Follow the steps below
With these steps, you will be forced to follow the django's authentication rules. So things will get more simple. |
Yes, i'm understand you now, Ok, my author model is now AuthorInfo :D, now, what have to do? |
Depends. django-permission is a logic based permission system while django-gurdian is a database based permission system. django-permission is much more flexible than django-gurdian. If you need complicated permission system, probably you would prefer django-permission. However, a permission logic will be executed on
Well I already explained. |
Yes but i don't understand you. I'm foolish newie. |
Preparationhttps://github.com/lambdalisue/django-permission#configuration UsageSimpleWrite the following code in your class Article(models.Model):
...
from permission import add_permission_logic
from permission.logics import AuthorPermissionLogic, StaffPermissionLogic
add_permission_logic(Article, AuthorPermissionLogic(
field_name='author',
any_permission=False,
change_permission=True,
delete_permission=True,
))
# It will use django's staff attribute. While you said you want to distinguish admin and
# django's staff, you might want to use GroupInPermissionLogic or your own permission
# logic here.
add_permission_logic(Article, StaffPermissionLogic(
any_permission=False,
change_permission=True,
delete_permission=True,
)) Done while you don't need your own views. AdvancedFollow https://github.com/lambdalisue/django-permission#autodiscovery Examples in real world |
Ok, but, this works with django admin? and how can created publish_permission? :D Now i have this from django.db import models
from django.template.defaultfilters import slugify
from django.core.urlresolvers import reverse
from django.contrib.auth.models import User
from authors.models import Author
from subtopic.models import Subtopic
from topic.models import Topic
from keywords.models import KeyWord
#Global Vars
# Create your models here.
class New(models.Model):
author = models.ForeignKey(User, verbose_name='Autor', related_name='news')
content = models.TextField(verbose_name='Contenido')
created_date = models.DateTimeField(auto_now_add=True, verbose_name='Fecha y Hora')
is_published = models.BooleanField(verbose_name='Publicada', default=False,) #Nueva, para verificar si se publica o no
keywords = models.ManyToManyField(KeyWord, blank=True, verbose_name='Palabras Clave', related_name='news')
place = models.CharField(max_length=255, verbose_name='Lugar')
source = models.URLField(verbose_name='Fuente', blank=True)
subtopic = models.ForeignKey(Subtopic, verbose_name='Subtema', related_name='news') #Filtramos por Opinion para sacar todas las columnas
times_viewed = models.PositiveIntegerField(default=0, editable=False, verbose_name='Veces Vista' )
title = models.CharField(verbose_name='Título', max_length=255, unique=True)
slug = models.SlugField(verbose_name='Slug', max_length=100, unique=True)
topic = models.ForeignKey(Topic, verbose_name='Tema', related_name='news', )
class Meta:
ordering = ['-created_date']
verbose_name_plural = 'Noticias'
verbose_name = 'Noticia'
#@models.permalink
#def get_absolute_url(self):
# return ('news.views.New_view', None, {'year': self.dateTime.year,
# 'month': self.dateTime.strftime('%m'),
# 'day': self.dateTime.strftime('%d'),
# 'slug': self.slug})
def first_image(self):
return self.images.first() # Siendo images el related_name en Image
def first_video(self):
return self.videos #Devuelve el video de la imagen
def get_absolute_url(self):
return reverse ('NewsDefaultView', args = [str(self.created_date.strftime("%Y")), str(self.created_date.strftime("%m")), str(self.created_date.strftime("%d")), str(self.slug)])
def get_all_keys(self):
keys_list = self.keywords.values_list('name', flat=True)
return str(keys_list).strip("'[]'").replace("'",'')
#def is_published(self): devuelve si la noticia ha sido pulicada para que salga en la lista de noticias
def __str__(self):
return self.title
def save(self): #Definir metodo para guardar, validar y otros metodos del Slug
super(New, self).save() #Solo con este me funciona correctamente
if not self.id:
self.slug = slugify(self.title)
super(New, self).save()
from permission import add_permission_logic
from permission.logics import AuthorPermissionLogic, StaffPermissionLogic
add_permission_logic(New, AuthorPermissionLogic(
field_name='author',
any_permission=False,
change_permission=True,
delete_permission=True,
))
add_permission_logic(New, StaffPermissionLogic(
any_permission=False,
change_permission=True,
delete_permission=True,
))
from django.core.cache import cache
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.contrib.sessions.models import Session
@receiver(post_save)
def clear_cache(sender, **kwargs):
if sender != Session:
cache.clear() |
Yes but you have to create youw own "publish" command. Read the django's document |
well, my publish commant is a boleean field, admin can push this in truth, but Author can't it. |
Well the publish permission is not object permission and you can do what you want with django's builtin permission system. Read the django's document carefully. Or write your own permission logic. Read what I said and the links I posted carefully then you will know how. |
Well, my models now is this: from django.db import models
from django.template.defaultfilters import slugify
from django.core.urlresolvers import reverse
from django.contrib.auth.models import User
from authors.models import Author
from subtopic.models import Subtopic
from topic.models import Topic
from keywords.models import KeyWord
#Global Vars
# Create your models here.
class New(models.Model):
author = models.ForeignKey(User, verbose_name='Autor', related_name='news')
content = models.TextField(verbose_name='Contenido')
created_date = models.DateTimeField(auto_now_add=True, verbose_name='Fecha y Hora')
is_published = models.BooleanField(verbose_name='Publicada', default=False,) #Nueva, para verificar si se publica o no
keywords = models.ManyToManyField(KeyWord, blank=True, verbose_name='Palabras Clave', related_name='news')
place = models.CharField(max_length=255, verbose_name='Lugar')
source = models.URLField(verbose_name='Fuente', blank=True)
subtopic = models.ForeignKey(Subtopic, verbose_name='Subtema', related_name='news') #Filtramos por Opinion para sacar todas las columnas
times_viewed = models.PositiveIntegerField(default=0, editable=False, verbose_name='Veces Vista' )
title = models.CharField(verbose_name='Título', max_length=255, unique=True)
slug = models.SlugField(verbose_name='Slug', max_length=100, unique=True)
topic = models.ForeignKey(Topic, verbose_name='Tema', related_name='news', )
class Meta:
ordering = ['-created_date']
verbose_name_plural = 'Noticias'
verbose_name = 'Noticia'
permissions = (
("can_publish", "Can publish news"),
)
#@models.permalink
#def get_absolute_url(self):
# return ('news.views.New_view', None, {'year': self.dateTime.year,
# 'month': self.dateTime.strftime('%m'),
# 'day': self.dateTime.strftime('%d'),
# 'slug': self.slug})
def first_image(self):
return self.images.first() # Siendo images el related_name en Image
def first_video(self):
return self.videos #Devuelve el video de la imagen
def get_absolute_url(self):
return reverse ('NewsDefaultView', args = [str(self.created_date.strftime("%Y")), str(self.created_date.strftime("%m")), str(self.created_date.strftime("%d")), str(self.slug)])
def get_all_keys(self):
keys_list = self.keywords.values_list('name', flat=True)
return str(keys_list).strip("'[]'").replace("'",'')
#def is_published(self): devuelve si la noticia ha sido pulicada para que salga en la lista de noticias
def __str__(self):
return self.title
def save(self): #Definir metodo para guardar, validar y otros metodos del Slug
super(New, self).save() #Solo con este me funciona correctamente
if not self.id:
self.slug = slugify(self.title)
super(New, self).save()
from permission import add_permission_logic
from permission.logics import AuthorPermissionLogic, StaffPermissionLogic
add_permission_logic(New, AuthorPermissionLogic(
field_name='author',
any_permission=False,
change_permission=True,
delete_permission=True,
))
add_permission_logic(New, StaffPermissionLogic(
any_permission=False,
change_permission=True,
delete_permission=True,
))
from django.core.cache import cache
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.contrib.sessions.models import Session
@receiver(post_save)
def clear_cache(sender, **kwargs):
if sender != Session:
cache.clear() |
Again, read the django's document, or ask on google group django users This is django-permission's issue (or questions). I'm welcome to answer the questions which related to django-permission but others. I'm sorry but your questions (how to create permissions, how to create admin commands, how to check permissions on admin, or so on) are completely not related to django-permission now. These questions are non of my business. |
The django-permission and django-guardian can coexist? |
Yes, if you are careful enough for confliction (e.g. django-guardian say Yes but django-permission say No for permission A of object A or whatever).
It sounds you don't need object permission. |
I tried but if I add the permission "can add group member", the user can add a new member only in the respective group. |
No idea while I don't know what you've tried or what you want to do. |
I need to have a permission, that let the users of a specific group to add,
delete or remove only for the specific group.
Now is more clear?
Sorry for my english
2017-11-17 18:35 GMT+01:00 Alisue <notifications@github.com>:
… I tried but if I add the permission "can add group member", the user can
add a new member only in the respective group.
Do you think is possible?
No idea while I don't know what you've tried or what you want to do.
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#28 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AVdMg-fTu0M4Zt7FuTTbwxXH-lFpHdxoks5s3cPEgaJpZM4Can_g>
.
|
Sorry for late. Do you have code? |
@lambdalisue No problem, I have fixed with groups_manager and django-guardian. Now i have a bug in admin panel for this issue |
ic. wish you can solve the problem 👍 |
Thank you for support! I try to solve the problem 👍 |
Good Nights, this is a question, not a issue.
I need to do two types of users, and default admin and author user.
An aditional permission for two users, Admin can publish news, author can't.
Author only can created news, and only edit and delect his own news.
A friend say me that for the second restrictions i need per object permissions, but i don't know how do all of this.
Can you help me?
The text was updated successfully, but these errors were encountered: