GenericForeignKey and Admin in Django

Say I have a Post object that can contain images, videos, and other types of media. I can use GenericForeignKey to bind them together. Something like:

 class Post(models.Model): title = models.CharField(...) text = models.TextField(...) class AudioMedia(models.Model): ... class VideoMedia(models.Model): ... class ImageMedia(models.Model): ... class MediaObject(models.Model): post = models.ForeignKey(Post) order = models.IntegerField() content_type_media = models.ForeignKey( ContentType, limit_choices_to={ 'model__in': ( 'audiomedia', 'imagemedia', 'videomedia') }) object_id_media = models.PositiveIntegerField() obj = generic.GenericForeignKey('content_type_media', 'object_id_media') 

Now I can easily create an admin interface, for example:

 class MediaObjectAdminInLine(admin.StackedInline): model = MediaObject ct_field = "content_type_media" ct_fk_field = "object_id_media" extra = 0 class PostAdmin(admin.ModelAdmin): inlines = [MediaObjectAdminInLine] 

Now the question is :) In admin /, I can easily create a new Mail. I can easily add another MediaObject to the message. In the panel, I have a drop-down menu to select the type (audio, video, ...), but I need to manually enter the identifier of the object that I want to associate with the message.

I tried various extensions, including grappelli. Some of them provide the ability to search for an object identifier for a link here. I want the ability to add objects here, for example, add AudioMedia, VideoMedia, ImageMedia, depending on what I choose from the drop-down list.

Any suggestions?

+8
django django-models django-admin
source share
3 answers

You will need to work hard to achieve this.

  • You ask that the administrator dynamically displays the model model based on what type of model you have selected from the drop-down list.
  • The Django administrator does not do this (and does not make any known extensions).

To complete this work, you need to:

  • Write a custom JavaScript event handler that displays a drop-down on model selection.
  • It then calls the Django administrator and requests the built-in model model for this model.
  • Refreshes the current HTML page with this model form.
  • Then you need to intercept the parent model model () () method to find out which child model it is dealing with and correctly store it in the database.
  • Then you will need to figure out how to get the model model of the parent model to correctly display the corresponding model model of the child’s model depending on the child’s model.

Is it hard to sound? It.

It’s easier here:

You just have one model of "Media". You will have several fields on the model that are valid for only one of your types (although there is a lot of crossover).

Name any fields that belong to the same media type with a prefix for this media type, i.e. image_size', or video_title`.

Attach a JavaScript handler to your ModelAdmin, which selectively displays and hides fields based on the drop-down list for the media type. Something like that:

 class MediaAdmin(admin.ModelAdmin): class Meta: js = ["js/media-types.js",] // media-type.js (function($) { $(document).ready(function(){ $('.module[id^=module] .row').hide(); $('.module[id^=module] .row.module').show(); $('.module[id^=module] .row.module select').each(function(){ if ($(this).val() != '') { var group = $(this).parent().parent().parent().parent(); var field = $(this).parent().parent().parent(); var mtype = $(this).val().toLowerCase(); if (mtype != '') { $('.row', group).not(field).slideUp('fast'); $('.row[class*="'+mtype+'"]', group).slideDown('fast'); $('.row[class*="all"]', group).slideDown('fast'); } else { $('.row', group).not(field).slideUp('fast'); } } }); $('.module[id^=module] .row.module select').change(function(){ var group = $(this).parent().parent().parent().parent(); var field = $(this).parent().parent().parent(); var mtype = $(this).val().toLowerCase(); if (mtype != '') { $('.row', group).not(field).slideUp('fast'); $('.row[class*="'+mtype+'"]', group).slideDown('fast'); $('.row[class*="all"]', group).slideDown('fast'); } else { $('.row', group).not(field).slideUp('fast'); } }); }); })(django.jQuery); 
+4
source share

I understand that this is quite old, but this is still the first search result.

django-admin-genericfk does exactly what you need.

0
source share

django-admin-genericfk does not work with Django 1.9.

Other than that, I found only the following module:

https://github.com/lexich/genericrelationview

which looks in good condition. Unfortunately, his JS code does not work well with the way Django CMS installs jQuery (noConflict jQuery), so it seems like this is not an option for me. But this should be good if you don't use CMS pages in Django other than the regular Django admin.

0
source share

All Articles