Django: change inlines based on select option

时光毁灭记忆、已成空白 提交于 2019-12-05 05:40:58

问题


Category has "types" (for example, three types of categories). Each category may have any number of Videos. And each Video, published in Category of '1' type may have any number of Pictures. But for Video, published in '2' and '3' Category types there are no Pictures.

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,]

question:

When i add Video item, and selecting Category for it, how can i dinamically show PictureInline based on what type of Category i selected for Video?

If i select first Category in select list, i want to be ablle to see PictureInline in admin, and if i select other Categories, i didn't want to see PictureInline.

Is it possible?

PS: I found https://github.com/digi604/django-smart-selects but didn't find such functionality for inlines


回答1:


Just use JavaScript to dynamically hide/show the inline set. The id of the inline set is always #[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')

Add the following to VideoAdmin:

class VideoAdmin(admin.ModelAdmin):
    ...
    class Media:
        js = ('path/to/this.js',)

Or override templates/yourapp/video/change_form.html with:

{% extends 'admin/change_form.html' %}
{% block extrahead %}
    {{ block.super }}
    <script src="path/to/this.js" type="text/javascript"></script>
{% endblock %}

UPDATE:

I've changed the JavaScript above to include an AJAX request. You're going to have to use AJAX because you've got to fetch the selected Category before you can get the type of it. I've also added a basic view you can use to return the data you need. You just need to hook the view up in your urls.py and change the URL in the AJAX call to match.



来源:https://stackoverflow.com/questions/6506439/django-change-inlines-based-on-select-option

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!