包含Select2的Django 2.0问题。如何在标准Django Admin中使用ForeignKey
(autocomplete_fields
)多步选择的模型?
我的tours
应用是:
游/ models.py :
class Tours(models.Model):
country = models.ForeignKey(Countries, on_delete=None, default=None)
resort = models.ForeignKey(Resorts, on_delete=None, null=True, default=None)
游/ admin.py :
@admin.register(Tours)
class ToursAdmin(admin.ModelAdmin):
list_display = ('country', 'resort',)
autocomplete_fields = ('country', 'resort',)
这是我的countries
应用:
国家/ models.py :
class Countries(models.Model):
name = models.CharField(max_length=255)
class Resorts(models.Model):
name = models.CharField(max_length=255)
country = models.ForeignKey(Countries, on_delete=models.CASCADE, default=None)
国家/ admin.py :
class ResortsInlineAdmin(admin.StackedInline):
model = Resorts
@admin.register(Countries)
class CountriesAdmin(admin.ModelAdmin):
list_display = ('name',)
search_fields = ('name',)
inlines = [ResortsInlineAdmin,]
@admin.register(Resorts)
class ResortsAdmin(admin.ModelAdmin):
list_display = ('name', 'country',)
search_fields = ('name',)
在Country
字段中选择值后会很好 - 仅在Resort
字段中保留与此Country
inlines
中的countries/admin.py
选项相关的值
与PHP + jQuery类似的demo。
答案 0 :(得分:1)
答案太简单了,但我在谷歌工作了很长时间。
首先,为tours/admin.py
(ModelAdmin.change_view()
)添加了额外的背景信息:
# tours/admin.py
@admin.register(Tours)
class ToursAdmin(admin.ModelAdmin):
list_display = ('country', 'resort',)
autocomplete_fields = ('country', 'resort',)
def change_view(self, request, object_id, form_url='', extra_context=None):
extra_context = extra_context or {}
extra_context['resort_to_country'] = Resorts.objects.all().values_list('pk', 'country_id')
return super().change_view(
request, object_id, form_url, extra_context=extra_context,
)
接下来,使用JavaScript改进templates/admin/tours/add_form.html
,如下所示:
// on bottom, into <script></script> tag:
var resort_to_country = [
{% for i in resort_to_country %}
['{{ i.country }}', {{ i.pk }}, '{{ i.name }}'],
{% endfor %}
];
var resorts_select_field = django.jQuery('#id_resort');
var countries_select_field = django.jQuery('#id_country');
countries_select_field.on('change', function () {
resorts_select_field.empty();
resort_to_country.forEach(function (item) {
if (item[0] === countries_select_field.find(':selected').text()) {
resorts_select_field.append(django.jQuery('<option></option>').attr('value', item[1]).text(item[2]));
}
});
});
这就是全部。