Login

Admin Hack: Quick lookup of GenericForeignKey id by ContentType

Author:
adnan
Posted:
September 25, 2008
Language:
JavaScript
Version:
Not specified
Score:
5 (after 5 ratings)

Generic Relations with django.contrib.contenttypes.generic.GenericForeignKey work well for models but the admin interface just shows the object id as an integer with no easy way to lookup the id of a new object. This jquery javascript adds a "Lookup <ContentType Name>" link next to the object id field in the admin interface.

This is done by reusing the showRelatedObjectLookupPopup() function provided with django which is used when the field is included in raw_id_fields (a little magnifying glass linked to popup object selector shows up). This essentially works the same way but changes which model's objects are shown and selected in the popup based on the ContentType selected for object_type

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
photo/models.py:

    # (c) CareerGrub - http://www.careergrub.com - Interactive Media and Web Technology Jobs


    from common.models import City, State, Country, Region

    class Photo(models.Model):
        # this could be a Region, Country, State, City, 
        object_type = models.ForeignKey(ContentType, null=True, blank=True)
        object_id = models.PositiveIntegerField(null=True, blank=True)
        content_object = generic.GenericForeignKey("object_type", "object_id")    


templates/admin/photo/photo/change_form.html:

    # (c) CareerGrub - http://www.careergrub.com - Interactive Media and Web Technology Jobs
    {% extends "admin/change_form.html" %}

    {% block extrahead %}{{ block.super }}
    <script type="text/javascript" src="/site_media/js/jquery-1.2.6.min.js"></script>
    <script>
     $(document).ready(function(){
    	 $(".object_id").append("<div id='lookup_box'></div>");
	 $("#id_object_type").change(function () {
          var type = $("#id_object_type option:selected").text();
          var good_choice = true;
          if (type == 'city' || type == 'state' || type == 'country' || type == 'region') {
			  var link_root = '../../../common/';
			  $("#lookup_box").html("<a onclick='return showRelatedObjectLookupPopup(this);' id='lookup_id_object_id' class='related-lookup' href='../../../common/region/'>lookup</a>");
	          $("#lookup_id_object_id").text("Lookup " + type);
	          $("#lookup_id_object_id").attr('href', link_root + type + '/');
          } else {
          	  $("#lookup_box").html("<span class='related-lookup' style='color: red;'>Invalid Choice! - Pick City, State, Country or Region</span>");
          }
        })
        .change();

     });
    </script>
    
    {% endblock %}

More like this

  1. Django Collapsed Stacked Inlines by applecat 1 year, 9 months ago
  2. Django Collapsed Stacked Inlines by mkarajohn 3 years, 10 months ago
  3. Dynamically adding forms to a formset. OOP version. by halfnibble 9 years, 6 months ago
  4. Convert multiple select for m2m to multiple checkboxes in django admin form by abidibo 11 years, 7 months ago
  5. Django admin inline ordering - javascript only implementation by ojhilt 11 years, 11 months ago

Comments

marcob (on December 13, 2008):

Nice!

You could check content_type in model:

content_type = models.ForeignKey(ContentType, limit_choices_to=Q(model='city') | Q(model='country') | Q(model='region') | Q(model='state'))

#

Please login first before commenting.