I have a django app. And I try in the admin panel of django restrict user permissions with the AUTHENTICATION AND AUTHORIZATION tab.
But I noticed that something is missing in my existing django app on the AUTHENTICATION AND AUTHORIZATION tab.
Because I installed a clean install from django. And the AUTHENTICATION AND AUTHORIZATION tab looked like:
and the AUTHENTICATION AND AUTHORIZATION tab in my existing django app looks like:
So as you can see in my existing django app the right part is missing of the user permissions.
What I have done? Is checking the versions. And they are the same(clean version and exsting version)
I am using django version: 5.0.6. and the libraries
I checked the libraries installed with pip freeze of my exisiting version:
anyio==4.2.0
asgiref==3.7.2
attrs==23.1.0
azure-common==1.1.28
azure-core==1.29.6
azure-storage-blob==12.19.0
azure-storage-common==2.1.0
certifi==2023.7.22
cffi==1.15.1
charset-normalizer==3.2.0
click==8.1.7
colorama==0.4.6
coreapi==2.3.3
coreschema==0.0.4
cryptography==39.0.0
defusedxml==0.7.1
Django==5.0.6
django-allauth==0.52.0
django-cors-headers==3.10.1
django-dotenv==1.4.2
django-filter==23.2
django-storages==1.14.2
djangorestframework==3.14.0
drf-spectacular==0.26.4
drf-yasg==1.20.0
exceptiongroup==1.2.0
gunicorn==21.2.0
h11==0.14.0
idna==3.4
inflection==0.5.1
isodate==0.6.1
itypes==1.2.0
Jinja2==3.1.2
jsonschema==4.19.0
jsonschema-specifications==2023.7.1
Markdown==3.4.4
MarkupSafe==2.1.3
oauthlib==3.2.2
packaging==23.1
Pillow==10.0.0
psycopg2==2.9.7
pycparser==2.21
PyJWT==2.6.0
pyrsistent==0.19.3
python-dateutil==2.8.2
python3-openid==3.2.0
pytz==2023.3.post1
PyYAML==6.0.1
referencing==0.30.2
requests==2.31.0
requests-oauthlib==1.3.1
rpds-py==0.10.2
ruamel.yaml==0.17.32
ruamel.yaml.clib==0.2.7
six==1.16.0
sniffio==1.3.0
sqlparse==0.4.4
typing_extensions==4.7.1
tzdata==2023.3
uritemplate==4.1.1
urllib3==2.0.4
uvicorn==0.23.2
waitress==2.1.2
And part of settings.py file of the existing app:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'drf_yasg',
'corsheaders',
'rest_framework.authtoken',
'django_filters',
'welAdmin',
"accounts",
"core",
'drf_spectacular',
]
LOGOUT_REDIRECT_URL = "/"
ACCOUNT_LOGOUT_REDIRECT_URL = "/"
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.TokenAuthentication',
],
'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema',
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
),
'SWAGGER_SETTINGS': {
'LOGIN_URL': 'rest_framework:login',
'LOGOUT_URL': 'rest_framework:logout'
}
}
# Password validation
# https://docs.djangoproject.com/en/4.1/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/4.1/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'CET'
USE_I18N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.1/howto/static-files/
STATIC_URL = '/static/'
MEDIA_URL = '/media/'
STATIC_DIRS = [
(BASE_DIR, 'static')
]
STATICFILES_DIRS = [BASE_DIR / 'static']
STATIC_ROOT = BASE_DIR / 'staticfiles/'
MEDIA_ROOT = BASE_DIR / 'media'
admin.py looks:
from django.contrib import admin, messages
from django.db import models
from django.forms import RadioSelect
from django.http import HttpResponseRedirect
from django.urls import reverse
from django.utils.safestring import mark_safe
from .models import Animal, Category
from .forms import SetCategoryForm
class AnimalAdmin(admin.ModelAdmin):
fields = ['name', 'sort', 'category', 'klasse_name', 'cites', 'uis', 'pet_list',
'description', "feeding", "housing", "care", "literature", 'images', 'img_preview']
readonly_fields = ['img_preview', 'klasse_name']
autocomplete_fields = ['category']
list_display = ('name', 'category_link', 'description')
search_fields = ['name', 'category__name']
search_help_text = "Zoek in de namen of families"
actions = ['set_category']
action_form = SetCategoryForm
ordering = ['id']
formfield_overrides = {
models.BooleanField: {"widget": RadioSelect(
choices=[(True, "Ja"), (False, "Nee")])}
}
def response_add(self, request, obj, post_url_continue=None):
if '_addanother' in request.POST:
url = reverse("admin:WelzijnAdmin_animal_add")
category_id = request.POST['category']
qs = '?category=%s' % category_id
return HttpResponseRedirect(''.join((url, qs)))
if '_continue' in request.POST:
return super(AnimalAdmin, self).response_add(request, obj, post_url_continue)
else:
return HttpResponseRedirect(reverse("admin:WelzijnAdmin_animal_changelist"))
def response_change(self, request, obj, post_url_continue=None):
if '_addanother' in request.POST:
url = reverse("admin:WelzijnAdmin_animal_add")
category_id = request.POST['category']
qs = '?category=%s' % category_id
return HttpResponseRedirect(''.join((url, qs)))
if '_continue' in request.POST:
return super(AnimalAdmin, self).response_change(request, obj)
else:
return HttpResponseRedirect(reverse("admin:WelzijnAdmin_animal_changelist"))
@admin.action(description="Zet de familie van de geselecteerde n")
def set_category(self, request, queryset):
category = request.POST['familie']
queryset.update(category=category)
messages.success(
request, '{0} animal(s) were updated'.format(queryset.count()))
def category_link(self, obj):
return mark_safe('<a href="{}">{}</a>'.format(
reverse("admin:WelzijnAdmin_category_change",
args=[obj.category.pk]),
obj.category.name
))
category_link.short_description = 'Familie'
class CategoryAdmin(admin.ModelAdmin):
fields = ['name', 'category', 'description', 'images', 'img_preview']
readonly_fields = ['img_preview']
autocomplete_fields = ['category']
list_display = ('name', 'category_link',
'subcategories_link', 'animals_link')
search_fields = ['name', 'category__name']
search_help_text = "Zoek in de namen of families"
actions = ['set_category']
action_form = SetCategoryForm
ordering = ['id']
def response_add(self, request, obj, post_url_continue=None):
if '_addanother' in request.POST:
url = reverse("admin:WelzijnAdmin_category_add")
category_id = request.POST['category']
qs = '?category=%s' % category_id
return HttpResponseRedirect(''.join((url, qs)))
if '_continue' in request.POST:
return super(CategoryAdmin, self).response_add(request, obj, post_url_continue)
else:
return HttpResponseRedirect(reverse("admin:WelzijnAdmin_category_changelist"))
def response_change(self, request, obj, post_url_continue=None):
if '_addanother' in request.POST:
url = reverse("admin:WelzijnAdmin_category_add")
category_id = request.POST['category']
qs = '?category=%s' % category_id
return HttpResponseRedirect(''.join((url, qs)))
if '_continue' in request.POST:
return super(CategoryAdmin, self).response_change(request, obj)
else:
return HttpResponseRedirect(reverse("admin:WelzijnAdmin_category_changelist"))
@admin.action(description="Zet de familie van de geselecteerde families")
def set_category(self, request, queryset):
category = request.POST['familie']
queryset.update(category=category)
messages.success(
request, '{0} categories were updated'.format(queryset.count()))
def category_link(self, obj):
if obj.category:
return mark_safe('<a href="{}">{}</a>'.format(
reverse("admin:WelzijnAdmin_category_change",
args=[obj.pk]),
obj.category
))
return None
category_link.short_description = 'Familie'
def subcategories_link(self, obj):
if obj.subcategories.exists():
return mark_safe('<a href="{}">{}</a>'.format(
reverse("admin:WelzijnAdmin_category_changelist") +
f"?category={obj.id}",
"Subgroepen"
))
return None
subcategories_link.short_description = "Subgroepen"
def animals_link(self, obj):
if obj.animals.exists():
return mark_safe('<a href="{}">{}</a>'.format(
reverse("admin:WelzijnAdmin_animal_changelist") +
f"?category={obj.id}",
""
))
return None
animals_link.short_description = "in groep"
admin.site.register(Animal, AnimalAdmin)
admin.site.register(Category, CategoryAdmin)
I have also a accounts app. and the admin.py looks like:
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from .models import Account
# Register your models here.
class AccountAdmin(UserAdmin):
list_display = (
"email",
"first_name",
"last_name",
"username",
"last_login",
"date_joined",
"is_active",
)
list_display_links = ("email", "first_name", "last_name")
filter_horizontal = ('groups', 'user_permissions',)
readonly_fields = ("last_login", "date_joined")
ordering = ("-date_joined",)
filter_horizontal = ()
list_filter = ()
fieldsets = ()
# Register your models here.
admin.site.register(Account, AccountAdmin)
# admin.site.register(Account, AccountAdmin)
Question: How to show the choosen user persmissions in the existing django app?
You unset the filter_horizontal
with filter_horizontal = ()
, remove that line:
class AccountAdmin(UserAdmin):
list_display = (
'email',
'first_name',
'last_name',
'username',
'last_login',
'date_joined',
'is_active',
)
list_display_links = ('email', 'first_name', 'last_name')
filter_horizontal = (
'groups',
'user_permissions',
)
readonly_fields = ('last_login', 'date_joined')
ordering = ('-date_joined',)
# filter_horizontal = () 🖘 remove
list_filter = ()
fieldsets = ()