Is it possible to only display custom premissions in django admin? - django

I want to display only custom permissions (which I have created with Meta class in Model) in Django admin interface. Is that possible and how?

I would consider creating your own custom view to add the custom permissions, instead of trying to modify the Django admin. However, if you're sure you want to use the Django admin, you could try the following approach:
Start by subclass UserChangeForm, and override the __init__ method. Set self.fields['user_permissions'].queryset with a queryset containing your custom permissions.
from django.contrib.auth.forms import UserChangeForm
class MyUserChangeForm(UserChangeForm):
def __init__(self, *args, **kwargs):
super(MyUserChangeForm, self).__init__(*args, **kwargs)
custom_permissions = ????
self.fields['user_permissions'].queryset = custom_permissions
Next, subclass django.contrib.auth.admin.UserAdmin, and use your form instead of the UserChangeForm.
from django.contrib.auth.admin import UserAdmin
class MyUserAdmin(UserAdmin):
form = MyUserChangeForm
Finally, unregister the default UserAdmin, and register your own.
admin.site.unregister(User)
admin.site.register(User, MyUserAdmin)

Related

Django: extended user with proxy model to add extra method, how to use the method in template?

I extend the default user model with a proxy model to add an extra method.
from django.contrib.auth.models import User
class Person(User):
class Meta:
proxy = True
def custom_method(self):
pass
The main purpose is to use the method in templates.
<div>{{ user.custom_method }}</div>
But since the user is pointing to the default user model, it has no access to the custom_method.
Is there any way to achieve this other than create a subclass of the User model?
=== UPDATE ==============
I ended up with custom backends:
(not sure if this solution has any drawbacks)
# user proxy
class ExtendedUser(get_user_model()):
class Meta:
proxy = True
def custom_method(self):
...
# backends
from django.contrib.auth.backends import ModelBackend
# since I'm using allauth
from allauth.account.auth_backends import AuthenticationBackend
from .models import ExtendedUser
class DjangoModelBackend(ModelBackend):
def get_user(self, user_id):
print("\n\n\ncustom user!!!")
try:
user = ExtendedUser.objects.get(pk=user_id)
except ExtendedUser.DoesNotExist:
return None
return user if self.user_can_authenticate(user) else None
class AuthModelBackend(DjangoModelBackend, AuthenticationBackend):
pass
And in settings.py, add these to AUTHENTICATION_BACKENDS.
It might be better to monkey patch the user model. Indeed, in one of the AppConfigs [Django-doc] we can implement this with:
# app_name/apps.py
from django.apps import AppConfig
from django.contrib.auth import get_user_model
def custom_method(self):
return 'Some value'
class MyAppConfig(AppConfig):
name = 'app_name'
def ready(self):
User = get_user_model()
User.custom_method = custom_method
Here we thus add a method to the user model that can then be called in views, templates, etc.

How to remove username from Django registration 1.0

I have customize Django 1.5 (from djangoproject docs) authentication to login with email instead of username and its working perfect, but I am using Django-registration 1.0 to register users.
How do I remove the username field from django registration so users will only need to enter e-mail & password when registering.
Thank you all in advance.
Yaniv M
This should get you started.
Create your own form that is a subclass of RegistrationForm.
In forms.py
from registration.forms import RegistrationForm
class MyRegistrationForm(RegistrationForm):
# Override RegistrationForm
def __init__(self, *args, **kwargs):
super(RegistrationForm, self).__init__(*args, **kwargs)
self.fields.pop('username')
In views.py
from registration.views import RegistrationView
from yourapp.forms import MyRegistrationForm
class MyRegistrationView(RegistrationView):
form_class = MyRegistrationForm
In urls.py
url(r'^accounts/register/$', MyRegistrationView.as_view(),
name='registration'),
You can create a custom form class based on default RegistrationForm and use that class in the RegistrationView view.
As-is, it's complicated. You need to:
apply this patch because in d-r-1.0, models.py assumes your User model has a "username" field
create your own "backend" by copy/pasting/editing registration/backends/default/views.py
copy/paste/edit the registration form as well from registration/forms.py
most of the time you can use the registration views without modification

Django admin - change permissions list

Is there any possibility to change permissions list in user edit page? I don't wan't to show all of permissions for example admin log entry or auth group etc.
How can I modify a main queryset to exclude some of it?
I got the idea from this topic, which also answer your question, but it's not that clear.
You have to overwrite the queryset of user permissions in the UserAdmin form used for visualization.
To do this, the easiest way is to create a subclass of UserAdmin and overwrite the get_form method:
from django.contrib.auth.models import User
from django.contrib.auth.admin import UserAdmin
class MyUserAdmin(UserAdmin):
def get_form(self, request, obj=None, **kwargs):
# Get form from original UserAdmin.
form = super(MyUserAdmin, self).get_form(request, obj, **kwargs)
if 'user_permissions' in form.base_fields:
permissions = form.base_fields['user_permissions']
permissions.queryset = permissions.queryset.filter(content_type__name='log entry')
return form
You can change the filter of your queryset for whatever you want:
Examples:
# Exclude admin and auth.
permissions.queryset = permissions.queryset.exclude(content_type__app_label__in=['admin', 'auth'])
# Only view permissions of desired models (Can be your models or Django's)
permissions.queryset = permissions.queryset.filter(content_type__model__in=['blog', 'post', 'user', 'group'])
After you create your class, you have to register your User model with your newly created Admin:
admin.site.unregister(User) # You must unregister first
admin.site.register(User, MyUserAdmin)
Edit:
I added comment from Maik Hoepfel, because this code made django crashed when creating new user.
You can do the same with the permission list in your Group edit page, but you have to create another Admin that extends from GroupAdmin, and change form.base_fields['user_permissions'] with form.base_fields['permissions']
Renato's answer is almost perfect. The Django Admin makes adding a user a two-step process with the same form, and his code fails with a KeyError for 'user_permissions' in the first step.
The fix is easy enough, just use the code below instead:
def get_form(self, request, obj=None, **kwargs):
form = super(MyUserAdmin, self).get_form(request, obj, **kwargs)
# adding a User via the Admin doesn't include the permissions at first
if 'user_permissions' in form.base_fields:
permissions = form.base_fields['user_permissions']
permissions.queryset = permissions.queryset.filter(content_type__name='log entry')
return form

Django - Adding a custom button to generate a random password using APG

I want to add a custom button which will generate a random password using APG in one of the Django models. I'm not sure which template I need to overwrite. Any ideas on how this can be accomplished?
Here is the screen shot of the admin and the other panel where I want to create the button.
Rather than overriding the template, why don't you override the Admin model for your User and the password form and put in the link to generate the password there. The link would likely trigger some javascript that could generate the random password for you, display it, and populate the field. Here's some untested code...
from django.contrib.auth.admin import UserAdmin
from django.contrib.admin.sites import NotRegistered
try:
admin.site.unregister(User)
except NotRegistered:
pass
class CustomUserForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(CustomUserForm, self).__init__(*args, **kwargs)
self.fields['password'].help_text = "PUT YOUR CODE HERE"
class CustomUserAdmin(UserAdmin):
form = CustomUserForm

django override User model

I'm trying to override the default User model in Django to add some logic into the save() method. I'm having a hard time trying to figure out out to go about this.
I'm using Django 1.1 if that helps.
I used post_save since i need to add the user into ldap.. I just added this into a models.py
from django.db import models
from django.contrib.auth.models import User
from django.db.models import signals
from django.dispatch import dispatcher
def user_post_save(sender, instance, **kwargs):
print "got here"
models.signals.post_save.connect(user_post_save, sender=User)
Don't. Instead catch the pre_save signal.
You'd better use a Proxy model, so to use the same table but overriding behavior.
This is the standard way to extend Django's own models, because they cannot be made abstract.
So declare your model as:
from django.contrib.auth.models import User
class CustomUser(User):
class Meta:
proxy = True
def save(self, *args, **kwargs):
# do anything you need before saving
super(CustomUser, self).save(*args, **kwargs)
# do anything you need after saving
and you are done.