Django:根据选择选项改变内联内容
这个内容讲的是一个分类系统,里面有不同的“类型”。比如说,有三种类型的分类。每个分类可以有任意数量的视频。而且,属于“1”类型分类的视频可以有任意数量的图片。但是,属于“2”和“3”类型分类的视频是不能有图片的。
models.py:
class Category(models.Model):
title = models.CharField()
CHOICES = (
('1','1'),
('2','2'),
('3','3'),
)
type = models.CharField(choices=CHOICES)
class Video(models.Model):
category = models.ForeignKey(Category)
class Picture(models.Model):
video = models.ForeignKey(Video)
title = models.Charfield()
admin.py:
class PictureInline(admin.TabularInline):
model = Picture
extra = 5
class VideoAdmin(admin.ModelAdmin):
inlines = [PictureInline,]
问题:
当我添加一个视频项目,并为它选择分类时,如何根据我选择的分类类型动态显示图片的输入框?
如果我在下拉列表中选择第一个分类,我希望在管理界面能看到图片的输入框;而如果我选择其他分类,我就不想看到这个输入框。
这样做可以吗?
附注: 我找到了一个链接 https://github.com/digi604/django-smart-selects,但没有找到可以用来处理这种情况的功能。
1 个回答
2
你只需要用JavaScript动态地隐藏或显示内联集合。这个内联集合的ID总是以#[related_name]-group
的形式出现。
(function($){
$(document).ready(function(){
function togglePictureInline(selected) {
$.getJSON('/ajax/category-type/', { id: selected }, function (data, jqXHR) {
if (data[0].fields.type == 1)
$('#pictures-group').show();
else
$('#pictures-group').hide();
});
}
var $category = $('#id_category');
togglePictureInline($category.val());
$category.change(function(){
togglePictureInline($(this).val());
});
});
})(django.jQuery);
yourapp/views.py
from django.shortcuts import get_list_or_404
from django.core import serializers
def ajax_category_type(request):
id = request.GET.get('id')
categories = get_list_or_404(Category, id=id)
data = serializers.serialize('json', categories, fields=('type',))
return HttpResponse(data, mimetype='application/json')
在VideoAdmin
中添加以下内容:
class VideoAdmin(admin.ModelAdmin):
...
class Media:
js = ('path/to/this.js',)
或者用以下内容覆盖templates/yourapp/video/change_form.html
:
{% extends 'admin/change_form.html' %}
{% block extrahead %}
{{ block.super }}
<script src="path/to/this.js" type="text/javascript"></script>
{% endblock %}
更新:
我已经修改了上面的JavaScript,加入了一个AJAX请求。你需要使用AJAX,因为你必须先获取所选的类别,才能知道它的类型。我还添加了一个基本的视图,你可以用来返回所需的数据。你只需要在你的urls.py中连接这个视图,并把AJAX调用中的URL改成相应的。