Set different admin index pages for each users - django

I am customizing the django admin. I want to set a different index page for staff users and keep the original for superusers.
What I have done is to add a view that looks like this:
def home(request):
if request.user.is_superuser:
return HttpResponseRedirect("/admin/new_admin/")
else:
return HttpResponseRedirect("/admin/new_admin/orders/")
But there is an extra problem:
There is a loop with the url "/admin/new_admin/"
I don't know if this is the best way to do it.
This is my urls.py
urlpatterns = patterns('',
(r'^admin/$', 'new_admin.views.home'),
(r'^admin/', include(admin.site.urls)), # admin site
)
Can anybody help me?
Thanks

Related

Django Class-based Views - ListView if User Is Authenticated, FormView if User is Not, Same URL

When a visitor is logged out and visits my homepage, I want them to see a registration form. When the user logs in, they will be redirected back to the homepage, but it will show a listview-like view.
Is the best way to achieve this to subclass both ListView and FormView and override each method necessary to get the behavior I want? Or is there a better way? Checking if the user is authenticated in each method doesn't seem like the Django way to do this. Hoping there's a smart design pattern approach for doing this that I don't know about.
class HomepageView(ListView, FormView):
def get_template_names(self):
if self.request.user.is_authenticated:
return ['homepage/loggedin_index.html']
else:
return ['homepage/loggedout_index.html']
def get_context_data(self, **kwargs):
if self.request.user.is_authenticated:
...
else:
...
def ... and so on
My must-have requirement is that the URL for both logged-in and logged-out users must resolve to the root URL since it's a homepage.
from django.urls import path
from .views import HomepageView
app_name = 'homepage'
urlpatterns = [
path('', HomepageView.as_view(), name='index'),
]
There is also a CreateListView that do what you want. And then you can change its form to the one you want.

Restricting admin urls to already authenticated superusers in Django

I've searched around for some solutions to this, but they all focus on a single admin url. However I was wondering if there is a way to restrict ALL the admin views, not the accounts to already authenticated superusers.
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^accounts/', include('accounts.urls'))
]
What I want is
urlpatterns = [
url(r'^admin/', is_superuser(admin.site.urls)),
url(r'^accounts/', include('accounts.urls'))
]
Or something like this that I can do in the view
#user_passes_test(lambda u: u.is_superuser, login_url='allauth.account.views.LoginView')
def superuser_only(request, template):
return render(request, template)
but still allows me to use admin.site.urls.
Is there a quick and elegant way to solve this? I want all users including the superuser to authenticate through accounts app.
You could create a middleware class that checks the request.path and the user and add it to the MIDDLEWARE var in your settings.
from django.http import Http404
class SuperUserMiddleware(object):
def process_request(self, request):
user = request.user
is_anonymous = user.is_anonymous()
if 'admin' in request.path
if not is_anonymous:
if not user.is_superuser:
raise Http404
else:
raise Http404

Django - how to implement an example.com/username url system

I am trying to implement on my website a simple and friendly address system.
What i'm thinking about is when the user logged in, his username will be displayed in the address bar.
www.example.com/username1 (for home page profile)
www.example.com/username1/about/
www.example.com/username1/gallery/
www.example.com/username2 (for home page profile)
www.example.com/username2/about/
www.example.com/username2/gallery/
And additionally if anyone enter the address www.example.com/username1, will be shown the profile of user1.
I already implemented a register/Login system using Django-Allauth
mySite/urls.py
url(r'^accounts/', include('allauth.urls')),
home/urls.py
url(r'^$', views.index),
home/views.py
def index(request):
return render_to_response('home/index.html', context_instance=RequestContext(request))
I tried to follow some examples like Facing problem with user profile url scheme like example.com/username in django
But i dont have this thing working yet. I dont understand what to do :(
Please, give some advise.
Add the following url as the last item of the mySite/urls.py:
urlpatterns = patterns('',
...
url(r'^(?P<username>\w+)/', include('userapp.urls')),
)
Then the username parameter will be passed to the views of your userapp:
userapp/urls.py:
from userapp import views
urlpatterns = patterns('',
url(r'^$', views.profile, name='user_profile'),
url(r'^about/$', views.about, name='user_about'),
url(r'^gallery/$', views.gallery, name='user_gallery'),
)
userapp/views.py:
def profile(request, username):
user = get_object_or_404(User, username=username)
return render(request, 'userapp/profile.html', {'profile_user': user})
def about(request, username):
...
def gallery(request, username):
...
It's almost perfect, but i have a bug. Let me explain. When i login (my login system is: django-allauth) on the http://127.0.0.1:8000/accounts/login/ i return to http://127.0.0.1:8000 with an error 404.
I am not getting the http://127.0.0.1:8000/username/ with the template, when the login botton is clicked.
The instalation of django-allauth require adding to the settings.py
LOGIN_REDIRECT_URL = '/'
How can i redirect to http://127.0.0.1:8000/username/ and show the correct template?
1. Regarding
How can i redirect to
Based on the answer from https://stackoverflow.com/a/20143515/4992248
# settings.py:
ACCOUNT_ADAPTER = 'project.your_app.allauth.AccountAdapter'
# project/your_app/allauth.py:
from allauth.account.adapter import DefaultAccountAdapter
class AccountAdapter(DefaultAccountAdapter):
def get_login_redirect_url(self, request):
return 'request.user.username' # probably also needs to add slash(s)
Would be better to use get_absolute_url, ie return 'request.user.get_absolute_url'. In this case you need to do:
# 1. Add `namespace` to `yoursite/urls.py`
urlpatterns = patterns('',
...
url(r'^(?P<username>\w+)/', include('userapp.urls', namespace='profiles_username')),
)
# 2. Add the code below to the Users class in models.py
def get_absolute_url(self):
# 'user_profile' is from the code shown by catavaran above
return reverse('profiles_username:user_profile', args=[self.username])
2. Regarding
show the correct template
catavaran wrote correct urls which leads to views.profile, so in view.py you need to write:
from django.shortcuts import render
from .models import UserProfile # import model, where username field exists
from .forms import UserProfileForm # import Users form
def profiles(request, username):
user = get_object_or_404(UserProfile, username=username)
return render(request, 'home/profiles.html', {'user_profile_form': user})
In template (i.e. profiles.html) you can show user's data via {{user_profile_form.as_p}}

Django Admin: Change URL links in change_list page

I would like to change the URL links in the change_list page from default to something else.
I have gone through the code of Admin and have to say, I need help.
Can anyone help me out???
Example:
In the above pic, I want to change the link under "Abhilash Nanda" to some other link. This for all the rows I may have. I would like to go from this change list page to another change list page where I can again list the rows from a related table to the clicked link.
You can edit the admin URL by extending the admin model. Like this.
class MyModelAdmin(admin.ModelAdmin):
def get_urls(self):
urls = super(MyModelAdmin, self).get_urls()
my_urls = patterns('',
(r'^my_view/$', self.my_view)
)
return my_urls + urls
def my_view(self, request):
# custom view which should return an HttpResponse
pass
You can here the full documentation here.

How to pass user instance to a view in Django

I am making a blog app where I want to make a view that displays all the blogs of a particular user. For this I need to pass the user instance to my view as
def blogs(request,author=None,slug=None):
# If the author context has been passed then display the blogs of that author
if author:
# Displays a particular blog
if slug:
this_blog = get_object_or_404(Entry, creator = author, slug = slug)
return render_to_response('blog/blog_view.html', {'blog': this_blog,},context_instance=RequestContext(request))
# Displays all the blogs of a particular user
else:
blog_list = Entry.objects.filter(creator = author)
return render_to_response('blog/all_blogs_user.html', {'Blogs': blog_list},context_instance=RequestContext(request))
Although syntactically this is correct but now I do not how to actually pass this user context in my url. Earlier I tried passing just the user id but that does not work. Is there any other alternative to doing this thing. When I am building the url internally or redirecting to this particular view then it is fine, but how would the url look like externally. My urls.py is as
from django.conf.urls.defaults import patterns, include, url
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
from django.views.generic.simple import direct_to_template
urlpatterns = patterns('',
url(r'^$', 'blog.views.blogs', name='all_blogs'),
url(r'^(?P<author>\d+)/(?P<slug>[-\w]+)/$', 'blog.views.blogs', name='view_blog'),
url(r'^(?P<author>\d+)/(?P<slug>[-\w]+)/edit/$', 'blog.views.post_form', name='edit_blog'),
url(r'^new/$', 'blog.views.post_form', name='new_blog'),
url(r'^(?P<author>\d+)/(?P<slug>[-\w]+)/delete/$', 'blog.views.delete_blog', name='delete_blog'),
)
urlpatterns += staticfiles_urlpatterns()
It generally works like this:
urls.py
url(r'/author/(?P<slug>/$', 'author_index'),
views.py
def author_index(request, slug):
author = get_object_or_404(User, username=slug)
return render_to_response('author_index.html', {
'author': author,
}, context_instance=RequestContext(request))
You can simply access the user in the view by request.user. Similarly, you can POST data in the request object as well.