I have added an app to my existing django site and to view it, I created an extra permission overview.view. But, I do not see it in my admin page, so I can also not assign this permission to any user. I think I have all files setup correctly, but I guess I am missing something. I have all the same files in the overview folder as I have in other working folders.
I do see the page, but somehow I am not logged in either.
This is my urls.py:
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index')
]
models.py:
from django.db import models
class Overview(models.Model):
class Meta:
permissions = (
('view', "May view the overview"),
)
and (part of) settings.py
INSTALLED_APPS = [
'overview.apps.OverviewConfig'
]
Permissions are stored in the database and so when you add or remove them via the Meta for the model the same is not of course automatically reflected in the database. Permissions are added post the migrations via a post_migrate signal connected from the auth apps appconfig's ready method. See the source code [GitHub]:
post_migrate.connect(
create_permissions,
dispatch_uid="django.contrib.auth.management.create_permissions"
)
Hence when one makes changes to the permissions one needs to run makemigrations and migrate to make sure they are added to the database.
Related
I have added account app to installed_apps in my django project.
also I have added urls of account app as like below:
(r"^account/", include("account.urls"))
Its working fine.
Now I had to override SignupView class of account app. This is also working fine.
Now I have created a new class CreateUser(SignupView) and I want that only admin user will be able to create user. So I added a different url for CreateUser(SignupView) view.
Now I want that account/signup url with view SignupView will not be accessible anymore.
How can I block this particular url by keeping other urls active of account app as this is a library.
You can add a specific entry for the one URL that you wish to block before you include the packages urls.py. This will take precedence as Django loops over URLs in order looking for the first match
from django.views.generic.base import RedirectView
urlpatterns = [
path('account/signup', RedirectView.as_view(url='/')),
path('account', include('account.urls')),
]
Is there anyway to delete django admin login page (mySite.com/admin) and use the user session which has logged in in main site (mySite.com)?
If any code is needed please tell me to add.
My middleware in settings.py is:
MIDDLEWARE = [
'django.contrib.sessions.middleware.SessionMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
.
.
.
.
.
]
update:
the reason is I want the admin first logs in with his account in website then open admin page. Other users would see admin link, but after clicking that they would see a message you don't have permission to see or change anything and they see nothing else. I just want myWebsite.com/admin be redirected to admin:index if the user is logged in and to myWebsite.com if he is not.
You can easily do this using your main urls.py file. Just redirect the admin login URL to your custom log-in page on your website. In the below sample you will notice the normal admin.site.urls being used AFTER admin/login and admin/logout (I assume you'll also have a custom log-out page). With these custom views being first they will take precedence and be used instead of the ones in admin.site.urls.
urlpatterns = [
url(r'^admin/login', your_custom_login_view, name='custom_login_page_admin'),
url(r'^admin/logout', your_custom_logout_view, name='custom_logout_view_admin'),
url(r'^admin/', admin.site.urls),
]
Create a custom subclass of AdminSite and overwrite the login() method. Something like this:
class CustomAdminSite(admin.AdminSite):
def login(self, request, extra_context=None):
if not request.user.is_authenticated:
# not authenticated, redirect to main login page
login_path = reverse('login')
return HttpResponseRedirect(login_path)
if self.has_permission(request):
# Already logged-in, redirect to admin index
index_path = reverse('admin:index', current_app=self.name)
return HttpResponseRedirect(index_path)
else:
# Logged in, but doesn't have required permissions
return render(...) # render a template with your error message
Follow the Django documentation on how to customize the AdminSite class.
Why you want to do that? Admin Page is for admin purposes, just dont access /admin/ path anymore or just remove admin from your urls.py, doign that you will not be able to access admin pages anymore...
But if you want to make your users access your django admin native pages using your custom login page, just make sure to tag your users with is_staff so they can access native django pages...
models.py
from django.contrib.auth.models import User
class CustomUser(User):
... # Your new fields
views.py
def create_user(request):
...
user, created = CustomUser.objects.get_or_created(
... # Your Custom + User Django fields
is_staff = True # This will allow this user to access the admin page
)
If you want allow all your users to access your django admin pages without need to use Django Login Page you can override your CustomUser model to set all users with is_staff
class CustomUser(User):
... # Your new fields
def save(self, *args, **kwargs):
if not self.id: # This indentify if the registry is new...
self.is_staff = True
super(CustomUser, self).save(*args, **kwargs)
Obs.: Make sure your User models extends the Django User Auth, there 2... one more complex and one simple, check the docs
https://docs.djangoproject.com/en/2.0/ref/contrib/auth/
All mentioned solutions here might do a good job, but my solution would be a little different: If you want to redirect to your default login page and hide the django-admin, sth. simple like this is a good workaround:
urlpatterns = [
path('admin/login/', RedirectView.as_view(pattern_name='account_login', permanent=True)),
]
Of course the target route (here account_login) can be changed as desired.
I prefer this approach:
on urls.py
from .settings import LOGIN_URL
from django.views.generic import RedirectView,
from django.urls import path, include
from django.contrib import admin
urlpatterns = [
path('admin/login/', RedirectView.as_view(url=LOGIN_URL)),
path('admin/', admin.site.urls),
....
]
To disable admin just remove url(r'^admin/', admin.site.urls), from your main urls.py. Another things to clean are 'django.contrib.admin' from INSTALLED_APPS.
A real easy way to accomplish this is by doing 2 things:
Head to your settings.py file and add: ADMIN_ENABLED = False
Head to your main urls.py file which should have something that looks like:
from django.urls import path, include
urlpatterns = [
# path('admin/', admin.site.urls),
path('', include("landing.urls")),
]
and comment out the path to admin like in the above snippet.
Cheers!
I have a blog made with Django where I write posts in markdown. I would like to add a view in the bottom of the admin page for each instance of the class Entry (my blog post class) such that I can get a preview of what the markdown looks like, while I'm writing. Just as you get a preview here on Stack Overflow when you create a new post.
I already have an admin class extending ModelAdmin:
class EntryAdmin(admin.ModelAdmin):
list_display = ('title','created')
prepopulated_fields = {'slug': ('title',)}
Is it possible to modify ModelAdmin further, such that it loads a certain html file (blogpost.html) and shows it in the bottom of the admin page?
I made a picture to show exactly what I mean:
NB: I know there are various tools such as Django admin plus, that allows one to add views to the admin interface, but not for each instance of an object.
You can use markdownx for that:
pip install django-markdownx
project settings.py
INSTALLED_APPS =
#. . . .
'markdownx',
]
project urls.py
urlpatterns = [
#[...]
url(r'^markdownx/', include('markdownx.urls')),
]
and then collect static files.
python3 manage.py collectstatic
your models.py
from markdownx.models import MarkdownxField
class MyModel(models.Model):
myfield = MarkdownxField()
your app admin.py
from django.contrib import admin
from markdownx.admin import MarkdownxModelAdmin
from .models import MyModel
admin.site.register(MyModel, MarkdownxModelAdmin)
This should work.
I am trying to use Authtools for custom users in django.
I am following documentation from their site:
django-authtools.readthedocs
I started a new project, created admin.
Then I:
inserted authtools in INSTALLED_APPS.
inserted AUTH_USER_MODEL = 'authtools.User' in settings.py
in urls i did:
from django.conf.urls import url,include
from django.contrib import admin
from authtools import urls
from django.contrib import admin
from authtools import urls
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^accounts/', include('authtools.urls')),]
Finally I ran python manage.py migrate
and i received following:
django.db.migrations.exceptions.InconsistentMigrationHistory:
Migration admin.0001_initial is applied before its dependency
authtools.0001_initial on database 'default'.
I have no idea what is going on. Does anyone understand?
Thank you.
You need to add authtools to INSTALLED_APPS and set AUTH_USER_MODEL = 'authtools.User' before you do the initial migration.
Since it's a new project, it should be straight forward to drop the database, recreate it, then run migrate again.
I have to include multiple changes to djangos admin panel, so I decided to fork the django admin app into my own django project.
As I was working with this admin app I recognized, that the site registration and template handling differs from the apps, that are normally created in django.
For instance, I want to keep the old admin index.html template and view, for backup and safety reasons but the landing page should be replaced by a custom page.
For that of course I need to change admin/templates/index.html and /admin/sites.py respectively.
I copied the old index function in admin/sites.py to old_index.py and created a old_index.html in the template folder.
But if I try to reference to old_index.html in my new index.html with
old index
I got an NoReverseMatch-Exception thrown. Unfortunately I did not found more information about how the django admin app itself register new views and sites, so an example or description would be helpful.
Creating separate views for the admin app in the distinct other apps in my project is no real option, due the high amount of changes, that need to be done.
The main urls.py
from django.conf.urls import patterns, include, url
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
# Examples:
# url(r'^$', 'django_project.views.home', name='home'),
url(r'^polls/', include('other_app.urls', namespace="other_app")),
url(r'^admin/', include(admin.site.urls)),
)
The admin app itself does not provide a urls.py file and the views.py is exactely the same as in django.contrib.admin I just copied the function index to a new function called old_index, referencing to a template old_index.html.
Maybe the point did not get so clear, as I expected. I copied the whole admin app in my project and want to add a custom defined site to it, regardless where. But I failed to understand how sites and views are registered in the admin app itself, because the way is different from the custom apps you create normally in django.
So, is it possible (and how) to add a custom site in the django.contrib.admin app?
I think you need to create your own AdminSite for custom purposes and keep default as it is. More about this you can find here: https://docs.djangoproject.com/en/1.6/ref/contrib/admin/#adminsite-objects and here https://docs.djangoproject.com/en/dev/ref/contrib/admin/#multiple-admin-sites-in-the-same-urlconf
Update:
You need to edit get_urls method of AdminSite class - add:
url(r'^$', wrap(self.old_index), name='old_index')
to urlpatterns variable. And rename old index method to old_index.