admin – Parerga und Paralipomena http://www.michelepasin.org/blog At the core of all well-founded belief lies belief that is unfounded - Wittgenstein Wed, 30 Sep 2009 11:13:47 +0000 en-US hourly 1 https://wordpress.org/?v=5.2.11 13825966 Using jquery’s autocomplete in django admin: how about inlines? http://www.michelepasin.org/blog/2009/09/30/using-jquerys-autocomplete-in-django-admin-how-about-inlines/ http://www.michelepasin.org/blog/2009/09/30/using-jquerys-autocomplete-in-django-admin-how-about-inlines/#comments Wed, 30 Sep 2009 11:13:47 +0000 http://magicrebirth.wordpress.com/?p=345 I still haven’t solved this problem entirely, and I’ll tell you why. Well the issue has been addressed by many, and among them probably the first and most influential solution is Jannis Leidel’s ‘An autocomplete form widget for ForeignKey model fields’.

Leidel says:

[..] my question is, if this could be done on a more abstract level for enhancing relations. when having a foreignkey, you get the browse-icon (lens) right near the input-field. it´d be awesome to search the relations just by typing something into the field … the autocomplete-functionality should then search the related entries on the basis of the defined search-fields.

Here’s a nice screencast of the the result [UPDATE: unfortunately the screencast is not available anymore]:

Picture 1

Leidel’s solution is not a copy&paste type of thing, however it’s very useful to study his code so to understand what’s going on there, and then replicate it in your specific user-scenario. That’s exactly what several people have done.

Nonetheless, reusing is more agile that doing things from scratch, isn’t it? So, after a bit of research I reached the conclusion that the most interesting and reusable (meaning, plug-and-play) django implementations of jquery’s autocomplete are two:

  1. the admin extensions section of the django-extensions project on google code
  2. PROs: it extends django’s raw_input widget, so while you can make use of the autocomplete you can still click on the lens and select the object you want from a new objects-list window (see screencast below). Also, you can enter the id of the object and the autocomplete will fill in straightaway the human-readable form of it (not sure how useful it is, but I like it)
    CONs: supports only one-2-many relationships, that is, it doesn’t work with many2many or inlines

  3. another project on google code called – surprise – django-autocomplete !
  4. PROs: very compact (just one file, no new apps to include). Works with one2many AND many2many
    CONs: again, no support for inlines…

    After having a go with both of them I decided to use the first one [the admin extensions section of the django-extensions project], cause I don’t need many2many support and I really liked the fact that the standard ‘raw-id’ behaviour is still available. Here’s a nice screencast (by the way I just realized that this one has been made by Jannis Leidel too, so I guess it’s sort of an evolution of the previous one) [UPDATE #2: also this screencast is not available anymore! what’s going on with mr Leidel?]:

    Picture 3

    Conclusion: there’s only one BIG problem – it doesn’t work with inlines out-of-the-box ! I’m looking at extending it now… will keep you posted!

     

    ]]> http://www.michelepasin.org/blog/2009/09/30/using-jquerys-autocomplete-in-django-admin-how-about-inlines/feed/ 1 345 Django admin and MPTT #2 http://www.michelepasin.org/blog/2009/08/18/django-admin-and-mptt-2/ http://www.michelepasin.org/blog/2009/08/18/django-admin-and-mptt-2/#comments Tue, 18 Aug 2009 10:46:32 +0000 http://magicrebirth.wordpress.com/?p=275 This is a follow up to the previous post on managing and visualizing trees using django. I’ve been using MPTT quite a bit now and it’s great – also, I looked deeper into the admin integration (basically, the issue of being able of manage trees from within the admin).

    The major issue I had with the patch discussed in my previous post was the fact that it is mainly a javascript hack – everything is done in the browser – i.e. it looked wonderful but it didn’t really scale up. So if you had a lot of items in your tree (say thousands) the js-driven pagination (basically, hiding and showing things on demand) would crash – at least, it did that to me all the time!

    The solution has been to reuse the admin management section from the FeinCMS project – this is a great CMS created by a bunch of django-ers in Switzerland – it relies heavvily on django’s admin so they had the same problem when having to provide a way for users to add structure to the pages in a website. With some help from google and Matthias (tx! he’s one of the guys behind FeinCMS) I got it all working.. here’s the main steps:

    1. upgrade to django 1.1
    This might not be necessary, cause everything is supposed to work also with the previous release – I tried it with django 1.0 too but I had to fix a couple of urls to make it work (Basically media files which were not loaded properly). So, if you want a hassle-free installation just upgrade to django 1.1 ! (which is great btw)

    2. download and add feincms, mptt to you installed apps in settings.py
    As simple as that.

    INSTALLED_APPS = (
        ....
        'mptt',
        'feincms',
    )
    

    3. specify a url-path for feincms media in settings.py, and also a location (this may vary in your live server, if you want apache to serve these files directly).

    FEINCMS_ADMIN_MEDIA = '/feincms_media/'
    FEINCMS_ADMIN_MEDIA_LOCATION = '/My/local/path/to/feincms/media/'
    

    4. add a url handler for feincms media files in urls.py. Again, these settings are ok on a development server, on production phase you might wanna do things differently :-)

    from django.conf import settings
        urlpatterns = patterns('',
        .....
        (r'^feincms_media/(?P<path>.*)$', 'django.views.static.serve',
             {'document_root': settings.FEINCMS_ADMIN_MEDIA_LOCATION, 'show_indexes': True}),
    )
    

    5. register your hierarchical model with mptt, then remember to set the Meta option correctly.. this is needed for a correct display of the tree in the admin (obviously you need to run syncdb to create the table in the db!):

    from django.db import models
    import mptt
    
    class TreeNode(models.Model):
       name = models.CharField(max_length=50, unique=True)
       parent = models.ForeignKey('self', null=True, blank=True, related_name='children')
    
       def __unicode__(self):
                    return self.name
    
       class Meta:
              ordering = ['tree_id', 'lft']
    
    
    mptt.register(TreeNode,)
    

    6. create a model admin that inherits from feincms TreeEditor class:

    from django.contrib import admin
    from django.utils.translation import ugettext_lazy as _
    from django.conf import settings as django_settings
    from feincms.admin import editor
    from myproject.myapp.models import *
    
    class TreeNodeAdmin(editor.TreeEditor):
        pass
    
    admin.site.register(TreeNode, TreeNodeAdmin)
    

    End! That should be it! Let me know if I forgot something..
    Here’s a screenshot of the new tree-management admin page we created:

    Picture 1

    UPDATE 09/2009: how to add more actions to the tree bar.
    Just override the _actions_column method on the TreeNodeAdmin class, as follows::

    class TreeNodeAdmin(editor.TreeEditor):
            def _actions_column(self, page):
                    actions = super(TreeNodeAdmin, self)._actions_column(page)
                    actions.insert(0, u'<a href="add/?parent=%s" title="%s"><img
                           src="%simg/admin/icon_addlink.gif" alt="%s"></a>' %
                           (page.pk, _('Add child page'),
                           settings.ADMIN_MEDIA_PREFIX , _('Add child page')))
                   actions.insert(0, u'<a href="%s" title="%s"><img
                           src="%simg/admin/selector-search.gif" alt="%s" /></a>' %
                           (page.get_absolute_url(), _('View on site'),
                           django_settings.ADMIN_MEDIA_PREFIX, _('View on site')))
                    return actions
    
    admin.site.register(TreeNode, TreeNodeAdmin
    

     

    ]]>
    http://www.michelepasin.org/blog/2009/08/18/django-admin-and-mptt-2/feed/ 31 275