Django admin customization without changing the default templates - python

I have one admin page. Where I want to add some link such that on click on that link pop up should be visible where we can set some value and alert something. I Don't want to post something in back end. So How we can achieve this without downloading change_list.html and change_form.html from default django site packages.?

You can override admin templates. As the docs state, you override the block you are interested modifying the contents of that block, by placing it in a file in a certain directory, and naming it after what type of page you want to change.
It's all explained in the docs.

Related

django admin - depending on radio button choice, show different fields

I am trying to do this cool stuff in django admin
I have a model which has a ImageField. What I want is that the my other coworkers are able to decide if they want to upload image or just paste the image link.
like
<radio>: upload <radio>: link
and depending on choice, respective field (which is model's imageField) will show up for under these radio buttons.
how can I achieve this in django admin?
You'll need to add the additional field to your admin form class, then add some JavaScript to show or hide the appropriate field on page load, and also add an event handler to show the field to upload or paste in the link.
Both fields would need to allow blank=True and then you'd need to add a clean() method to make sure one of the fields is populated and then set the value appropriately. You might be better off using two separate fields.
You can leverage the Media inner class to easily add the JavaScript to the page without having to alter the change_form.html template for that app. Check out: https://docs.djangoproject.com/en/1.7/topics/forms/media/ for examples of how to add custom CSS and JavaScript to forms.

Ajax sidebar in Django

I'm doing a website for my school in Django. The blog part is almost ready, but on every page I want to have a sidebar with planned changes in the timetable (i.e. when a teacher is ill and classes will have lessons with another teachers in another classrooms). What would be the best way to implement that? I've heard about templatetags, RequestContext and other things like that. That is my first Django project and I'm learning new things every day.
Now I have one app in the project which is called blog (it's models are: Posts, Categories and Pages; Page is like a flatpage but it is assigned to a category by a ForeignKey). In project's urls.py every request (beside /admin) is forwarded to blog.urls where the further actions are taken (choosing the appropriate view class). Views are written using generic views and class inheritance. There are: PostListView, PostView, PageView. The PageListView is unneeded because user is able to choose Page from the main navbar.
The 'changes sidebar' should allow the user to choose a date and reload itself without reloading the whole page.
I would be really grateful if someone could help me with an idea on implementing it. If you have any questions - ask.
The 'changes sidebar' should allow the user to choose a date and
reload itself without reloading the whole page.
Ok, so you need AJAX for this part. For more complex projects you can use django-rest-framework or tastypie but for this I reccomend to do an AJAX function that gets a date as parameter and return a rendered template. See this thread and this one too
To include the sidebar, I'll just create a separate template for it and include {% include 'changes_sidebar.html' %} you also need to include the javascript to do the ajax requests.

How do you add a new entry into the django admin index?

I'm working on a Django project, and I've created some custom admin views using the get_urls override method described in the documentation. It works perfectly. There is just one problem. There is no way to get to this custom admin view unless you already know the URL.
There are some ways I already know of to add a link to this view somewhere in the admin, but none of them are satisfactory. I want a link to the custom view to appear in the model listings right with all the model admins. I just don't want it to have +add or +change links next to it because it isn't a model.
I could just override the admin_site or the template, but this is no good. It puts the customization on the project level instead of the app level. It also will only put the link on the /admin/ page and not the /admin/myapp/ page.
I could also just easily add the link in a different location by overriding the app_index.html template, but that is not exactly a convenient or intuitive place to look for it.
Another solution I came up with is to create a blank model and register a blank admin for it. Then steal the url patterns for that model so clicking on its entry goes to my custom view instead of to a blank add/change view. That works, but it's an incredibly ugly hack.
Here is a picture of what I'm trying to achieve.
I still think the correct way of doing this is overwriting some parts of django admin templates. There is no easy way of adding these links.
https://docs.djangoproject.com/en/dev/ref/contrib/admin/#overriding-vs-replacing-an-admin-template
I also found this article http://coffeeonthekeyboard.com/o-hai-django-adminplus-568/ which also suggests that django-adminplus is a good tool for doing this. Personally I prefer to keep clear of any extra dependancies and would still use templates - but thats up to you.
Have you tried this app: https://github.com/jsocol/django-adminplus? Even if it does not work for the exact purpose you are trying to achieve, at least it can give you some enlightement by checking out the code
You need to override the template admin/index.html. Thenput a new pair of tags after the {% endfor %} on line 40.
You might also be able to solve it using jQuery.

Remove the "Add" functionality in Django admin [duplicate]

This question already has answers here:
Django Admin - Disable the 'Add' action for a specific model
(5 answers)
Closed 10 years ago.
Is there a way to remove the "Add" functionality on the Django admin site? For certain entities, I only want the Django admin to be able to view them or change existing ones, but not add new ones.
See: Django Admin - Disable the 'Add' action for a specific model for true solution.
Sure, you can customize admin VERY granularly by following the instructions here -- I believe that what you want can be obtained in part by overriding ModelAdmin.save_model(self, request, obj, form, change) in your own ModelAdmin subclass, to ensure nothing happens on the store when change is false (i.e. an attempt to add rather than change), and in part by overriding ModelAdmin.add_view(self, request, form_url='', extra_context=None) to display an "add view" that makes it very clear to the admin that they're NOT going to be allowed to add object through this route. I haven't actually done the specific admin customization you require, but I've done others and they do seem to work pretty smoothly!
You can customize the permission for each user group from within the admin interface: try going to /admin/auth/group and it should be straightforward from there.
This won't be as granular as the solution offered by the earlier answer, but it will take care of most of your needs without needing to customize the admin.
If you change the permissions to restrict access then you'll still get the plus sign by a FK/MtM field. Clicking that will open a popup window with 'Permission Denied' in it.
You can actually completely remove the plus sign by not simply not registering the model with the admin.
I have a situation where I have predefined categories that I want users to be able to select more than one of. The best way to do this is with a models.ManyToMany field. You can register the model with the admin, enter the data as required and then remove the registration.
An easy effective way is to set max_num=0 for that particular inline.
Satya's suggestion of setting max_num=0 works perfectly.
Per the Django docs on the ModelForm class:
For users with JavaScript-enabled browsers, an "Add another" link is provided to enable any number of additional inlines to be added in addition to those provided as a result of the extra argument.
The dynamic link will not appear if the number of currently displayed forms exceeds max_num, or if the user does not have JavaScript enabled.
and
As with regular formsets, you can use the max_num and extra parameters to modelformset_factory to limit the number of extra forms displayed.
max_num does not prevent existing objects from being displayed

Django.contrib.flatpages without models

I have some flatpages with empty content field and their content inside the template (given with template_name field).
Why I am using django.contrib.flatpages
It allows me to serve (mostly) static pages with minimal URL configuration.
I don't have to write views for each of them.
Why I don't need the model FlatPage
I leave the content empty and just supply a template path. Therefore I can take advantage of having the source in a file;
I can edit the source directly from the file system, without the help of a server (such as admin).
I can take advantage of syntax highlightning and other editor features.
With the model I have to maintain fixtures for flatpages.
So the data for the same entity is in two seperate places.
If I move the content inside the fixture it'll be more difficult to edit.
Even if fixture maintenance was a non-issue I'd still need to dump and load these fixtures again and again during development.
What I am looking for
Basically; getting rid of FlatPage model while maintaining contrib.flatpages functionality. I don't have a clear idea how this should be solved. If there's a clean way of modifying (like add_to_class) FlatPages to get the information somewhere other than the database I'd prefer that. Maybe the metadata can be inserted to the templates and then a special manager that reads this data would replace the default manager of FlatPages.
If I don't prefer manual editing over admin functionality for flatpages, how can take the database out of the equation?
Using the direct_to_template generic view would be a lot simpler. You could use the passed in parameters on one view to specify the actual template in urls.py, if you don't want to add an entry for each page:
r'^foo/(?P<template_name>.+)/$','direct_to_template', {'template': 'foo_index.html'}),
Then import the template in your foo_index.html:
{% include template_name %}

Categories