How to add report section to the Django admin? - django

I want to implement a report section in Django admin. This would mean adding a custom section in the admin homepage where instead of a list of models I would see a list of reports. I want to use Django's admin tables with filters, sorting, everything if possible.
What would be the "best" way of achieving this? I realize this is a "big" question so I'm not asking for code snippets necessarily, a summary of needed actions would be just fine :)
P.S. Be report I mean a "made up" model by custom queries (queryset or how it's called).
P.S.2 Maybe this question should be something like: How to use Django admin tables functionality in own admin view?
P.S.3 Or maybe there is a way of providing to the existing admin interface my own data. This way I don't have to do anything else. I just want to say instead of a model take this data and display it in a nice table which I can sort, filter etc etc.

So you are attempting to add in new pages into the django admin.
This section explains to you exactly how you can do so - https://docs.djangoproject.com/en/dev/ref/contrib/admin/#adding-views-to-admin-sites
The basic idea is to add in new urls that you want in your urls.py as if you are adding urls for your "front end" pages. The key difference is that these new urls you are adding should start with ^admin/ and would look something like ^admin/my_special_link_in_admin and this url will point to your own custom view function at a location you so prefer.
E.g.
(r'^admin/my_special_link_in_admin/$', 'my_custom_admin_app.views.special_admin_page'),
So this is the way for complete customization. There's a very good tutorial which I refer to here - http://brandonkonkle.com/blog/2010/oct/4/django-admin-customization-examples/
In addition, if you don't want to do too much work, consider using Django Admin Plus - https://github.com/jsocol/django-adminplus
Or a django-admin-views - https://github.com/frankwiles/django-admin-views

Related

Django admin customization with non-related models

I am a django noob and am trying to figure out how to get the admin module to do something slightly different than the normal operation on a single model. Essentially what I need is to run a query and display the results of the query as a view page and then allow the link to the edit page take the user to an existing model's edit view. 2 of the 3 tables in my query are related, but not all 3.
Example:
select a.foo, a.second_field, b.bar, c.unrelated_field
from a, b, c
where a.primary_key = b.foreign_key
and a.some_value = c.some_value
Note that a and c are not defined as related tables.
I would like to have a view of this query output and have a link to the edit view of the b model as a whole when selected.
I have created a view in the DB for this query and simply created a new model which makes it easy to get the view, but I'm not sure this is even the right approach to start with...but from there I can't seem to figure out how to make this link to the edit page for the B table.
Any pointers or advice on how best to accomplish something like this with django admin would be appreciated!
Using Django 1.3.1 by the way.
Cheers!
You can override change_view in your ModelAdmin so it will construct a list of dicts with all your needed data. Then override change_list.html template to display this data correctly and link it with change_form view for correct model. So it will flawlessly integrate in Django's admin site.
And I don't like DB views as long as it's possible to solve the problem without it. If data can be constructed in Python without massive performance gaps and lots of magic code, it should be processed in Python.

Should I modify/extend the admin interface, or write my own CRUD views/templates?

I'm trying to write a simple CRM app in Django; partly as a learning exercise and partly for in-house use.
My schema is slightly complex, as rather that have a single Contact model (with a home phone, work phone, home email, etc.), I have stripped down Cntact model plus a Phone model, an Email model, etc., with a ForeignKey pointing back to a Contact. The point is to let Contacts have an arbitrary number of phone numbers, email addresses, etc. Simple, right?
I have some working views and templates for displaying the data - no issues there. And with only a very small amount of poking at admin.py I have a um...eight different TabularInlines set up, and the admin interface works to create and edit the data...but it's ugly and clunky to the point of unusability, and of course there's no conception of permissions or anything. I'm also not really a fan of having a completely different interface for displaying and searching through the data than for editing and adding contacts...I'd like as much as possible to be done inline, so that I can search for a name, look at the record, click "add note", have it popup a form, fill in the details, click submit, and be done, all with AJAXy goodness so there's no page reloads.
Question: Should I plug away at modifying the admin interface to try and make it usable for a user-facing app? And if so, can anyone point me to a good guide or example where someone has really changed the admin interface to make it work for user-facing CRUD operations?
Or should I just go ahead and write my own CRUD views? And if so, can anyone point me to a good guide or example where someone has written custom CRUD views that work with lots of ForeignKeys and inlines? Ideally I want a form that displays a single Contact, all his Email records, plus a blank form to add a new Email record, plus a button to add more blank forms, plus his Phone records, plus a blank form, and so on for all 8 of my associated models.
(Or am I thinking about this all wrong? Any advice appreciated.)
For our intranet, we use ModelAdmin subclasses (not mounted on the admin site via admin.site.register) for most of our C(R)UD views. By using custom templates for the views, it doesn't look like Django admin at all. What is very convenient though, is that it already handles all the validation/saving for us.
In general, I found admin-"hacking" quite useful to quickly write up C(R)UD views and usually with relatively small changes to your ModelAdmin subclass, you can make it work for your use case.
So I'd vote for use ModelAdmin, but not the one you use in admin, hook a different template and come up with some fancy CSS.
I successfully created a software on top of admin.
The admin hooks (these days) allow very fine-grained customizations, i.e. in general you only need to touch what you want to change.
The changes can go from a trivial cosmetic adjustment to a complete swap-out:
If you provide templates/admin/base.html your admin site can look any way you like. And of course, a navigation bar at the top could include links to some of your own views. Watch out not to hardcode URLs in your links, always reverse.
You can overload ModelAdmin's "change_view", "changelist_view" etc. and swap them for your own views. For example I replaced a default changelist and its simple filtering with a search interface that allows dynamic queries to be built, result columns to be customized by the user, and loading/saving of these searches. That didn't affect any of the other views of that ModelAdmin.
Overloading a ModelAdmin's "get_urls()" let's you rewrap existing admin urls to go to your own views. I did the latter for one model where I wanted the simple Add screen to be replaced by a totally customized Wizard (only leaning on ModelForm).
Don't forget the simplest approach, esp. regarding your "AJAXy goodness": Just define "css" and "js" in your ModelAdmin's Meta. Want to move an inline from the bottom to sit between third and fourth field, and that's not possible via parameters? A one-liner in jquery.
Check out "django-grappelli" for an example of how to improve admin look and feel.
What did you mean by "and of course there's no conception of permissions or anything"?

Django Admin: Need to conditionally display fields

What is the best way to conditionally display a field in the admin depending upon the values of other fields?
In particular I'm thinking about the add_form and change_form. Whenever a certain choice is selected I'd like to hide or disable some fields.
I'm thinking that this might require a javascript solution, but am wondering if there is a better (i.e. builtin) way to do this.
Bernhard is right. You might be able to hack the admin view and template to conditionally show/not show widgets for a field, but if you want to do it dynamically based on user behaviors in the admin, you'll be using javascript.
It's not so terrible, though. At least the Django admin templates have model- and instance-specific ids to give you granular control over your show/hide behavior.
My answer may sound esoteric - but I suspect the design direction you may be taking could benefit from some reconsideration. When an interface requires that much TLC to resort to AJAX to make for a superior UX I am inclined to not use Admin interface for that.
My personal view of the Admin interface of Django is that it is a great freebie that gives me an instant CRUD view at a basic level. I would refrain from piggy backing on it for those who need a more user friendly interface (even if some of these users are handling admin functions). You will acquire technical debt in trying to do these type of Ajax UI/UX and complex form validations using the Admin interface.
I think you should be able to create your own ModelForm and specify that the admin uses that (https://docs.djangoproject.com/en/1.7/ref/contrib/admin/#django.contrib.admin.ModelAdmin.form).
Use the _init__() method of the form to selectively display the fields.
I will give it a try and update this answer if it works.
(Actually re-reading the question, it depends. If "values of other fields" is set before the page is loaded, this idea should work. If you want an instant response - click one field and another appears/disappears, yes you will need JavaScript).

Use Django admin modules inside own forms

In the Django admin i have a customized changelist with added search and filters. I have been looking alot but cannot seem to find a way to use the whole "changelist module" outside of admin. So i can embed it in one of my own pages.
I do not need any of the authentication or anything like that. I just want to show a table (for a content management backend) that has the nice search, sort and filter capabilities.
Is there perhaps any documentation about doing this?
Of course you can use the ChangeList class for your own projects. I cannot give you a full documentation on doing so here, but some points to start with.
Have a look here to see how the
ChangeList has to be initialized in
your view. (The ChangeList class
lives at
django.contrib.admin.views.main, so
import it from there!)
Look at the admin templates to see how the
corresponding template tags are used.
(also this template)
Maybe you will also find the django.contrib.databrowse-application helpful!

Django - Static content display based on URL

I'm working on a Django site with a basic three column design. Left column navigation, center column content and right column URL specific content blocks.
My question is about the best method of controlling the URL specific content blocks in the right column.
I am thinking of something along the lines of the Flatpages app that will make the content available to the template context if the URL matches a pre-determined pattern (perhaps regex?).
Does anyone know if such an app already exists?
If not, I am looking for some advice about the best way to implement it. Particularly in relation to the matching of patterns to the current URL. Is there any good way to re-use parts of the Django URL dispatcher for this use?
Django CMS is a good suggestion, it depends on how deep you want to go. If this is just the beginning of different sorts of dynamic content you want then you should go that way for sure.
A simple one-off solution would be something like this:
You would just need to write a view and add some variables on the end of the URL that would define what showed up there. Depending on how fancy you need to get, you could just create a simple models, and just map the view to the model key
www.example.com/content/sidecontent/jokes/
so if "jokes" was your block of variable sidecontent (one of many in your sides model instances) the urls.py entry for that would be
(r'^content/sidecontent/(?P<side>)/$,sides.views.showsides),
and then in your sides app you have a view with a
def showsides(request, side):
Sides.objects.get(pk=side)
etc...
For something like this I personally would use Django CMS. It's like flatpages on steroids.
Django CMS has a concept of Pages, Templates, and Plugins. Each page has an associated template. Templates have placeholders where you can insert different plugins. Plugins are like mini-applications that can have dynamic model-based content.
Although Django-CMS is an interesting suggestion, there are quite a few projects that do specifically what you've requested - render blocks of content based on a URL. The main one that I know about is django-flatblocks.