Django Admin: Change URL links in change_list page - django

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.

Related

How to add a custom button in a registered model in django admin site

Can anyone guide me in the right direction on how to put a button next to the delete button ? I want to put a confirm and deny button next to it, that when I click it, it will send an email to the user that his/her application is accepted or denied. I've searched online for a solution and also read some similar questions here, but I am not sure whether or not those are right things to go to.
First make buttons for confirm and deny in list_page by writing confirmed() and denied() method , then you append your custom urls in admin urls by overriding get_urls() method and mapped those url to a view method confirmed_application() and denied_application().
After processing your logic then you can redirect same change_list page.
#admin.register(YourModel)
class YourModelAdmin(admin.ModelAdmin):
list_display = ['your_model_fields', 'confirmed', 'denied']
def confirmed(self, obj)
url = reverse('admin:confirm_url', kwargs={'id': obj.id})
return format_html('<a class="button" href="{}">Confirm</a>', url)
def denied(self, obj)
url = reverse('admin:denied_url', kwargs={'id': obj.id})
return format_html('<a class="button" href="{}">Deny</a>', url)
def get_urls(self):
urls = super().get_urls()
custom_urls = [
path('confirm/<int:id>', self.confirmed_application, name='confirm_url'),
path('deny/<int:id>', self.denied_application, name='denied_url'),
]
return custom_urls + urls
def confirmed_application(self, request, id):
# you get object_id you can do whatever you want
# you can send a mail
# after processed all logic you can redirect same modeladmin changelist page
redirect_url = "admin:{}_{}_changelist".format(self.opts.app_label, self.opts.model_name)
return redirect(reverse(redirect_url))
def denied_application(self, request, id):
# same as confirmed_application
...

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.

Django admin loads view template when url pattern is same as model name

I'm writing my first Django project in Django 2.0.
I noticed another weird behavior with Django urlpatterns.
I have an app starrednotes and model within it as Starred(models.Model)
same is the case with Shared(models.Model) within sharednotes app
I have configured the urlpattern for with path pattern same as the model name
urlpatterns = [
url(r'^starred/$', StarredNotes.as_view(), name='starred'),
url(r'^shared/$', SharedNotes.as_view(), name='shared'),
]
and view StarredNotes is
class StarredNotes(ListView):
template_name = 'notes/starred.html'
model = Starred
context_object_name = 'starred_notes'
def get_queryset(self):
starred_notes = Starred.objects.filter(user=self.request.user)
return starred_notes
#method_decorator(login_required)
def dispatch(self, request, *args, **kwargs):
return super(self.__class__, self).dispatch(request, *args, **kwargs)
The URL setup above is accessible using
http://example.com/notes/shared
http://example.com/notes/starred
But when I'm accessing these two models from admin with URL as
http://example.com/admin/sharednotes/shared
http://example.com/admin/starrednotes/starred
These two links are loading the template setup in the StarredNotes and SharedNotes class instead of admin template.
I can not understand why it is behaving like this. Is it a Django limitation or bug in Django.
Anyway here are two ways you can get rid of it.
1. Change urlpattern
change URL pattern and replace the pattern with something other than the model name.
In my case, this is how my urlpatterns looks now.
urlpatterns = [
url(r'^starred/$', StarredNotes.as_view(), name='starred'),
url(r'^shared/$', SharedNotes.as_view(), name='shared'),
]
2. Change model name
This is not the recommended way but you can rename your model to something else only if urlpattern is more important than the model. Changing model name may require changes to many other places as well.
class SharedNote(models.Model):
# model fields
class StarredNote(models.Model):
# model fields

Set different admin index pages for each users

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

Django admin override save behaviour

Using the Django Admin I would like to have a 'confirmation box' when someone presses the save button in the admin interface i.e. you are trying to update "name or age or sex" to "foo or 23 or m".
You could overwrite the get_form method in your model admin to add another check or the save() method to create a warning. You could also add an intermediate page (like the delete view does)...
i.e.
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
Read more: http://www.ibm.com/developerworks/web/library/os-django-admin/index.html?ca=drs
If you want a JavaScript method then I imagine you could just overwrite the admin view for that very easily and add a simple confirmation when save is click i.e.
Dave
As the OP is very slim, with no code examples I cannot really help beyond this general answer.