Monday, July 28, 2008

Stupid-Simple Django Admin Previews






Incase you didn't know, I love Django.


I love how Django just makes things stupid-simple, such as with its built-in automatic admin interface. Yet one thing it did not provide was an optional post-preview, where you could see exactly what your post will look like once it is live without others being able to see it.


For me this was a must-have feature. So I quickly thought up a stupid-simple way to add admin previews.



This technique works with or without newforms-admin and is insanely easy to implement.


This requires a general understanding of Django's generic views. It also requires that you have a model that you want to preview. This model must have some kind of 'draft' status that is not shown on your live site, but is saved in the database.


So, lets say you have a model called Article. To add a preview for each article:



  • Add a generic object_detail view to your app's views.py:



    from django.contrib.admin.views.decorators import staff_member_required
    from django.views.generic.list_detail import object_detail
    from your_app.models import Article


    @staff_member_required
    def preview(request, object_id):
    return object_detail(request, object_id=object_id,
    queryset=Article.objects.all(),
    template_object_name = 'article', )



    That @staffmemberrequired ensures that only people logged into your admin and designated a staff member for your site can see your article's preview before it is live. The rest is just a generic object_detail view named 'preview'.





  • Add a line to your app's urls.py, above your admin url line:


    url(r'^admin/your_app/article/(?P<object_id>[0-9]+)/preview/$',
    'your_app.views.preview'),






  • You don't actually have to add a template for the view if your project already has an object_detail template (named article_detail.html in this case). The generic view will grab this same template, and you'll be able to see exactly what your post will look like on your live site.





  • Lastly, add a template to: /templates/admin/your_app/article/change_form.html. Paste this into that template:



    {% extends "admin/change_form.html" %} {% load i18n %}
    {% block object-tools %}
    {% if change %}{% if not is_popup %}
    <ul class="object-tools">
    <li><a href="history/" class="historylink">
    {% trans "History" %}</a></li>
    <li><a href="preview/" class="viewsitelink" target="_blank">
    {% trans "View preview" %}</a></li>
    {% if has_absolute_url %}<li>
    <a href="../../../r/{{ content_type_id }}/{{ object_id }}/" class="viewsitelink">
    {% trans "View on site" %}</a></li>{% endif%}
    </ul>
    {% endif %}{% endif %}
    {% endblock %}






The beauty of that 'View preview' link is it will only appear on the change form for the appropriate model (in this case, Article) and only once the article has been saved to the database (so you must save it as a draft first).


So after you restart your server, every time you save an article as a draft, you'll be able to click a button and see exactly what your post will look like to the world, without the world having to see it. :)




django

No comments:

Post a Comment