在 Django 中,当你在管理界面编辑外键时,你会发现下拉列表中只包含了已经存在的对象,而无法创建新的对象。这对于某些场景来说可能不是很方便,比如你在创建新模型时需要选择一个外键,而又不想先创建这个外键对象。
2、解决方案 Django 提供了多种方法来扩展外键下拉选择器,以便在管理界面中可以选择已经存在的对象或创建新的对象。
方法一:使用 RawIdField
RawIdField 允许你在管理界面中输入外键对象的 ID,然后 Django 会自动加载这个对象。在 admin.py 中,你可以通过以下方式使用 RawIdField:
class BookInline(admin.TabularInline):
model = Book
raw_id_fields=('shelf',)
extra =1
class Shelf(admin.ModelAdmin):
inlines = [BookInline,]
方法二:使用 Select2
Select2 是一个 JavaScript 库,可以为你的下拉列表提供更丰富的功能,比如支持搜索和分页。在 Django 中,你可以使用 django-select2 库来集成 Select2。
在 admin.py 中,你可以通过以下方式使用 Select2:
from django.contrib.admin import widgets
class BookInline(admin.TabularInline):
model = Book
formfield_overrides = {
models.ForeignKey: {'widget': widgets.Select2Widget},
}
extra =1
class Shelf(admin.ModelAdmin):
inlines = [BookInline,]
方法三:使用 ModelForm
ModelForm 允许你在管理界面中使用表单来编辑模型。在 admin.py 中,你可以通过以下方式使用 ModelForm:
from django.forms import ModelForm
from django.contrib.admin import widgets
class BookForm(ModelForm):
class Meta:
model = Book
shelf = forms.ModelChoiceField(queryset=Shelf.objects.all())
class Shelf(admin.ModelAdmin):
form = BookForm
方法四:使用自定义视图
如果你需要更加复杂的自定义行为,你可以创建自定义视图来处理外键的选择。在 admin.py 中,你可以通过以下方式创建自定义视图:
from django.contrib.admin import ModelAdmin, AdminSite
from django.contrib import admin
class MyAdminSite(AdminSite):
def has_permission(self, request):
return True
class BookAdmin(ModelAdmin):
def change_view(self, request, object_id, form_url='', extra_context=None):
return super().change_view(request, object_id, form_url, extra_context)
def add_view(self, request, form_url='', extra_context=None):
return super().add_view(request, form_url, extra_context)
admin_site = MyAdminSite()
admin_site.register(Book, BookAdmin)
代码示例:
#models.py
class Book(models.Model):
title = models.CharField(max_length=200)
author = models.ForeignKey(Author, on_delete=models.CASCADE)
class Author(models.Model):
name = models.CharField(max_length=200)
#admin.py
from django.contrib.admin import ModelAdmin, TabularInline, site
from django import forms
class AuthorInline(TabularInline):
model = Book
class AuthorAdmin(ModelAdmin):
inlines = [AuthorInline]
site.register(Author, AuthorAdmin)
这样,当你在管理界面编辑作者时,你就可以在右侧看到所有属于这个作者的书籍,并且可以添加新的书籍。