I want to change the default url for django admin from /admin to /djadmin so that I can use /admin for my own purposes.
So far all I have done is update the urls.py file, changing the admin url to
url(r'^djadmin/', include(admin.site.urls)),
and then adding my own
(r'^admin/', include('my_app.admin_urls')),
However when I now navigate to /admin I get the following error
Forbidden
You do not have staff privileges.
Which since I don't require this parameter I assume is coming from an internal django check. If I change the user to have the is_staff flag checked then it works fine and redirects to my admin pages.
Is there something else I need to do to stop Django checking for the is_staff flag whenever I navigate to an admin url?
The is_staff flag is wrapped in the code of Django admin site, because is intended to restrict the usage of this interface only to a subgroup of selected users (the ones that administrate the content of the website). The only way to remove it is to subclass the Django's admin site, so a your own custom site.
For admin site customization see the official documentation or other answers like the one I've posted previously. In the AdminSite subclass you have to override the has_permission method with:
def has_permission(self, request):
return request.user.is_active
You also need to use a custom admin form (AdminSite.login_form) and modify the base.html template, removing references about is_staff in a pair of if statements.
Related
I am having trouble finding where this admin file exists so I can add an extra field. I think it's auto-magically created upon setup.
I want to add a date field, specifically, to the listing page (shown below), perhaps after the UID field so I can know when the user auth was created.
screenshot of django user social auths listing page
Okay here's what I've tried using Django-allauth and I think it somehow works the same with django-socialauth. Just get the gist of the idea and work it to your code
Extend first the SocialAccountAdmin in any of your admin.py files, better if in a specific app like "user", "home", or whatever you prefer.
admin.py
from allauth.socialaccount.admin import SocialAccountAdmin
from allauth.socialaccount.models import SocialAccount
class MySocialAccount(SocialAccountAdmin):
list_display = ('user', 'uid', 'provider', 'date_joined') # I haven't tried just adding a certain list to the list_display, for the meantime add all necessary fields just like how socialauth did
admin.site.unregister(SocialAccount) # Need to unregister the default socialaccount admin
admin.site.register(SocialAccount, MySocialAccount) # Then register it back with the custom made admin
There may be perhaps a better way to do this but this did the work.
Can it be interesting to just add a field to your model ? Adding a DateField for your creation date. Probably you need to understand learn more with : https://docs.djangoproject.com/en/3.0/ref/models/fields/
I'm really struggled by this. I looked through the Django documentation and I couldn't find a method to get the site_id of the currently logged in user_id with Sites framework.
I want to build a blogpost form and I wan't to include the site_id so that the content that the user publish will go to that particular site_id.
The user will only have permissions to publish to one site_id.
To clarify:
Publish content to the site_id that the user_id belongs to.
Is there a way to do this?
A user does not belong to a site. A request does.
If, somehow, in your Django project sites are owned by users, then you should add a new field to your User model. Something like this:
class MyUserModel(...):
...
blog = models.OneToOneField(Site)
The "Overview" section of the "User authentication in Django" documentation says that the authentication system in Django doesn't provide password strength checking. I wrote a form class that adds some basic password requirements such as minimum character length. I'm trying to implement it in Django's admin interface. As far as I know, there are three places I will need to implement my password requirements:
Creating a user: /admin/auth/user/add/
Changing a user's password: /admin/auth/user/1/password/
Changing my own password: /admin/password_change/
I can take care of the first two by subclassing UserAdmin and specifying add_form and change_password_form:
https://github.com/django/django/blob/1.8.2/django/contrib/auth/admin.py#L58-L59
How can I get the third one (changing my own password) to use my password requirements? The code is a little above me:
https://github.com/django/django/blob/1.8.2/django/contrib/admin/sites.py#L314
Obviously by sub-classing and using your own AdminSite
# my_admin.py
class MyAdminSite(AdminSite):
def password_change(self, request, extra_context=None):
...
site = MyAdminSite()
You can disable autodiscovery for default admin site, by using AdminConfig for INSTALLED_APPS settings (django 1.8+ only)
INSTALLED_APPS = (
'django.contrib.admin.apps.AdminConfig',
...
)
And then you have to manually register required models to your new admin site.
I am using django 1.4 and Python 2.7.
I just have a simple requirement where I have to add a new URL to the django admin app. I know how to add URLs which are for the custom apps but am unable figure out how to add URLs which are of the admin app. Please guide me through this.
Basically the full URL should be something like admin/my_url.
UPDATE
I want a way after which I can as well reverse map the URL using admin.
+1 for Jingo's answer to your original question. With your clarifying comment to the answer in mind:
Such a URL is not "independent of the apps", it is a URL for the app "admin".
Adding a URL to the admin site is similar to ModelAdmin, by overriding get_urls():
https://docs.djangoproject.com/en/dev/ref/contrib/admin/#adding-views-to-admin-sites
EDIT:
https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.AdminSite
is an admin site, by default "the" admin site is instantiated as "django.contrib.admin.site" (and then e.g. your ModelAdmin's are registered against that). So you can subclass AdminSite for your own MyAdminSite and re-define get_urls() there:
from django.contrib.admin import AdminSite
class MyAdminSite(AdminSite):
def get_urls():
...
...
my_admin_site = MyAdminSite()
...
my_admin_site.register(MyModel, MyModelAdmin)
Make sure you use my_admin_site in urls.py instead now:
https://docs.djangoproject.com/en/dev/ref/contrib/admin/#hooking-adminsite-instances-into-your-urlconf
Regarding the actual contents of get_urls(),see
https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.get_urls
(of course calling super() of MyAdminSite). Also note the convenient "admin_view" wrapper mentioned there.
P.S.: In theory, you could also just define get_urls() and then monkeypatch the default admin site so that it uses your get_urls() but I don't know if that would actually work - you'd probably have to monkeypatch right after its "first" import...
Just put your desired url mapping before the admin mapping in your root urls.py. The first match for the request will be taken, because django goes the url mappings from top to down. Just remember that you don't use an url the admin normally needs or provides because this will never match with a custom mapping in front of it. HTH!
I need to create a subdomain based authentication system, like the one 37signals, freshbooks, codebase use. That is, each subdomain of my main application needs to have its own username namespace. I would like to keep as much as possible of the django authentication system.
What is a good way to store the username?
In particular, it should be possible for different users to have the same username as long as their account belongs to a different subdomain.
Some approaches I've considered, for which I can foresee shortcomings:
storing some prefix in the username field of the django auth user model.
extending the user model according to this.
customizing the source of auth to my needs
I have built this functionality for several sites in the past and have found that your first bullet point is the way to go.
It means that you don't have to make massive change to django auth. What I did was set up a custom authentication backend that abstracts away the way usernames are stored.
auth_backends.py
from django.contrib.auth.backends import ModelBackend
from Home.models import Account
class CustomUserModelBackend(ModelBackend):
def authenticate(self, subdomain, email, password):
try:
user = Account.objects.get(username=u'%s.%s' % (subdomain, email))
if user.check_password(password):
return user
except Account.DoesNotExist:
return None
def get_user(self, user_id):
try:
return Account.objects.get(pk=user_id)
except Account.DoesNotExist:
return None
For this particular project Account was the user model and it just inherited directly from User however you could replace Account with whatever you want.
You have to install the custom auth backend in your settings file:
AUTHENTICATION_BACKENDS = (
'auth_backends.CustomUserModelBackend',
'django.contrib.auth.backends.ModelBackend',
)
Then when you call authenticate you need to pass in the subdomain, email and password.
You can also add some other helper functions or model methods that help with making sure that only the user's actual username is displayed, but that is all pretty trivial.
I think this may be a good use case for using django.contrib.sites in combination with the second bullet item you mentioned. You could create a CustomUser model like so:
from django.contrib.sites.models import Site
class CustomUser(User):
"""User with app settings."""
sites = models.ManyToManyField(Site)
Then you could write a custom auth backend to check that the user can sign in to the current subdomain using the supplied credentials. This allows you to have one username for multiple sites (subdomains) without having to hack the internal auth app or store multiple usernames with custom prefixes.
EDIT: you can get the current site by using Site.objects.get_current() and then check to see if the current site is in the user's sites.
You can read more about the sites framework here: http://docs.djangoproject.com/en/dev/ref/contrib/sites/