Django admin widget for displaying movies
Recently I had to make a widget for Django admin to display movies (H.264 encoded, MPEG-4 and FLV). We already have a widget for displaying the movie inline within the admin change form, but I had to create a widget that opens separate entity (lightbox-like overlay or popup browser window). For a start I took the popup browser — this seemed easier because one of the requirements was that the movie player will not load with the page (I am not that good in javascript, mind you...). What it takes to have a widget that shows some content in separate browser window?
- you can open window by manually appropriate javascript code, but I prefer to use some ready-made plugin for jQuery, like jquery-popupwindow;
- you'll need Django view (and template) that displays actual page with embedded player;
- to embed the player (which is Flash object) you'd need swfobject and the player itself, like JW Player (it plays both mp4 and flv movies — but watch out, it's free only for strictly non-commercial use);
- a Django's forms widget that will have something that can be clicked to open new window.
Now for the fun part: actual code. The widget code is a mish-mash of my previous experiences in writing custom Django widgets:
class AdminPopupMovieWidget(forms.FileInput):
class Media:
js = (
'js/jquery.js',
'js/jquery.popupwindow.js',
)
def render(self, name, value, attrs=None):
output = []
if value and hasattr(value, 'url'):
width = getattr(value, 'width', 600)
height = getattr(value, 'height', 500)
ctx = {
'url': value.url,
'href': '%s?url=%s' % (reverse('movie-show'), value.url),
'class': 'popupwindow',
'rel': 'width:%(width)d,height:%(height)d' % locals(),
}
output.append(u'<a href="%(href)s" class="%(class)s" rel="%(rel)s">%(url)s</a>' % ctx)
output.append(u'<br />')
output.append(super(AdminPopupMovieWidget, self).render(name, value, attrs))
output.append('''<script type="text/javascript">
$(".popupwindow").popupwindow();
</script>''')
return mark_safe(u''.join(output))
The code above produces a widget that has a clickable link with the title of movie URL. The anchor is linked to the URL of the view that produces HTML to display, like the code below:
@require_GET
def view_movie(request):
movie_url = request.GET.get('url')
if not movie_url:
raise Http404
ctx = {
'url': movie_url,
}
return render_to_response('movie/view.html', ctx,
context_instance=RequestContext(request))
The only variable that is passed in the context is the URL of the movie, but you are free to include as much as you'd like. Of course, nothing forces you to use urls, you can call the view with a PK to the movie-holding object, but this will require changes to the above view code.
But that's not all. You have to register your model in Django admin application. If you just register it with default modelform, the instances will display themselves with default admin widget. Two more classes are required:
class MovieAdminModelForm(forms.ModelForm):
movie = forms.CharField(widget=widgets.AdminPopupMovieWidget)
class Meta:
model = Movie
class MovieAdmin(admin.ModelAdmin):
form = MovieAdminModelForm
Is this all? Yes, I think.


