如何根据 Django admin 中的另一个选择标签选项更改选择标签选项?

Posted

技术标签:

【中文标题】如何根据 Django admin 中的另一个选择标签选项更改选择标签选项?【英文标题】:How to change select tag options according to another select tag's option in Django admin? 【发布时间】:2020-11-22 05:53:37 【问题描述】:

我在 admin.py 中有这个

class BrandAdmin(admin.ModelAdmin):
    list_display = ('name','category','date')
    form = BrandAdminForm
    class Media:
        js = ('own.js',)

admin.site.register(Brand,BrandAdmin)

和models.py

class Category(models.Model):
    name = models.CharField(max_length=100)

class Subcategory(models.Model):
    name = models.CharField(max_length=100)
    category = models.Foreignkey(Category, on_delete=models.CASCADE)

class Brand(models.Model):
    name = models.CharField(max_length=100)
    category = models.Foreignkey(Category, on_delete=models.CASCADE)
    subcategory = models.Foreignkey(Subcategory, on_delete=models.CASCADE)
    date = models.DateTimeField()

那么如何根据品类选择品牌子品类呢?

【问题讨论】:

【参考方案1】:
...
import json
...

class BrandAdminForm(forms.ModelForm):
    ''' collecting subcategories and corvert it to json. for use in javascript code '''
    data = 
    for cat in Category.objects.all():
        data[str(cat.id)]=
    for sub in Subcategory.objects.all():
        data[str(sub.category.id)][str(sub.id)] = 
                'id': str(sub.id),
                'cat_id': str(sub.category.id),
                'name': str(sub.name)
        
    data = json.dumps(data)
    ''' converted to json '''

    category = forms.ModelChoiceField(queryset=Category.objects.all(), 
    widget=forms.Select(attrs='onchange':  'category = this.options[this.selectedIndex].value; var data = ' + data + ';(function() var select = document.getElementById("id_subcategory");  select.options.length=0; select.options[select.options.length] = new Option("----",""); for(let [key, value] of Object.entries(data[category.toString()]))  select.options[select.options.length] = new Option(value.ady,value.id);  )()'));
    class Meta:
        model = Brand
        fields='__all__'


class BrandAdmin(admin.ModelAdmin):
    list_display = ('name','category','date')
    form = BrandAdminForm
    # class Media:
    #     js = ('own.js',)

admin.site.register(Brand,BrandAdmin)

只需复制粘贴此代码 所有你需要的 django-form 和一些 javascript 代码

widget = forms.Select(attrs=
    'onchange': 'category = this.options[this.selectedIndex].value;   #category on changed
     var data = ' + data + ';(function() 
     var select=document.getElementById("id_subcategory"); 
     select.options.length=0; 
     select.options[select.options.length] = new Option("----",""); 
     for(let [key, value] of Object.entries(data[category.toString()]))  
        select.options[select.options.length] = new Option(value.ady,value.id); 

)()'));

【讨论】:

以上是关于如何根据 Django admin 中的另一个选择标签选项更改选择标签选项?的主要内容,如果未能解决你的问题,请参考以下文章

根据同一模型中的另一个外键动态限制 Django 模型中外键的​​选择

Django admin 根据另一个字段值过滤一个外部字段

Django Admin 根据其他选择动态禁用字段

使用 Django 根据用户选择的另一个对象属性的值来过滤属性的对象值

如何从 django admin 中的单个“选择文件”选择器上传多个图像

LINQ - 如何根据仅存在于某些记录中的另一个元素选择一个元素