Django 管理 - 自定义列表外观和 ManyToManyField 键的选择
Django Administration - Customize list appearance and selection of ManyToManyField keys
我有一个包含 1000 多首歌曲的数据库。我有一个接受歌曲作为字段的自定义模型“Schedule”。
models.py
from django.db import models
class Song(models.Model):
title = models.CharField(max_length=255)
words = models.TextField()
slug = models.SlugField()
date = models.DateTimeField(auto_now_add=True)
snippet = models.CharField(max_length=50)
def __str__(self):
return self.title
class Schedule(models.Model):
songs = models.ManyToManyField(Song)
date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return str(self.date)
admin.py
from django.contrib import admin
from .models import Song, Schedule
@admin.register(Song)
class SongModel(admin.ModelAdmin):
search_fields = ('title',)
list_display = ('title',)
list_per_page = 100
@admin.register(Schedule)
class ScheduleModel(admin.ModelAdmin):
search_fields = ('date',)
list_display = ('date',)
list_per_page = 100
我希望能够将我想要的任何歌曲添加到时间表中,但是很难通过 Django 管理中的默认列表来实现,looks like this。我必须滚动并按 CTRL+select 每一个,然后添加它们。
我想要更实用的东西select、搜索等
我有哪些选择?我不知道从哪里开始寻找。
选项 1
只有当你的相关项目很少(时间表中的歌曲很少)时才会舒服。但它超级简单,而且会比你现在拥有的更好。 (django.contrib.admin 内置 select2。)
@admin.register(Schedule)
class ScheduleAdmin(admin.ModelAdmin):
...
autocomplete_fields = ("songs",)
选项 2
(upd: 妈的,一开始忘记了,还超级简单,还蛮高效的)
看起来还不错。可用。不是特别舒服。但总比按住 Ctrl 键单击要好。
@admin.register(Schedule)
class ScheduleAdmin(admin.ModelAdmin):
...
filter_horizontal = ('songs',)
选项 3
如果您想要一个舒适的 UI 而无需实施自定义页面或操作(不幸的是,它们完全是一团糟),您应该使用 StackedInline admin.
不过还是比较难。
首先,您需要在两个模型之间设置 through model. (I don't think inlines are possible with auto-generated many-to-many models.) It's basucally your many-to-many。类似的东西:
class ScheduleSongNM(models.Model):
song = models.ForeignKey("Song", null=False)
schedule = models.ForeignKey("Schedule", null=False)
告诉您的 Schedule
模型使用您的自定义通过模型:
class Schedule(models.Model):
songs = models.ManyToManyField(Song, through="ScheduleSongNM")
现在为 ScheduleSongNM
创建一个内联管理员:
class ScheduleSongInline(admin.StackedInline):
model = ScheduleSongNM
fields = ["song"]
autocomplete_fields = ["song"] # select2 works here too
最后,告诉您的 Schedule
管理员它现在有内联:
@admin.register(Schedule)
class ScheduleAdmin(admin.ModelAdmin):
...
inlines = [ScheduleSongInline]
...
也许我漏掉了什么(很明显我还没有测试过),但我想你已经明白了。最后,您会在 Schedule
管理界面中看到一个看起来像这样的框(加上歌曲名称的自动完成):
我有一个包含 1000 多首歌曲的数据库。我有一个接受歌曲作为字段的自定义模型“Schedule”。
models.py
from django.db import models
class Song(models.Model):
title = models.CharField(max_length=255)
words = models.TextField()
slug = models.SlugField()
date = models.DateTimeField(auto_now_add=True)
snippet = models.CharField(max_length=50)
def __str__(self):
return self.title
class Schedule(models.Model):
songs = models.ManyToManyField(Song)
date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return str(self.date)
admin.py
from django.contrib import admin
from .models import Song, Schedule
@admin.register(Song)
class SongModel(admin.ModelAdmin):
search_fields = ('title',)
list_display = ('title',)
list_per_page = 100
@admin.register(Schedule)
class ScheduleModel(admin.ModelAdmin):
search_fields = ('date',)
list_display = ('date',)
list_per_page = 100
我希望能够将我想要的任何歌曲添加到时间表中,但是很难通过 Django 管理中的默认列表来实现,looks like this。我必须滚动并按 CTRL+select 每一个,然后添加它们。
我想要更实用的东西select、搜索等
我有哪些选择?我不知道从哪里开始寻找。
选项 1
只有当你的相关项目很少(时间表中的歌曲很少)时才会舒服。但它超级简单,而且会比你现在拥有的更好。 (django.contrib.admin 内置 select2。)
@admin.register(Schedule)
class ScheduleAdmin(admin.ModelAdmin):
...
autocomplete_fields = ("songs",)
选项 2
(upd: 妈的,一开始忘记了,还超级简单,还蛮高效的)
看起来还不错。可用。不是特别舒服。但总比按住 Ctrl 键单击要好。
@admin.register(Schedule)
class ScheduleAdmin(admin.ModelAdmin):
...
filter_horizontal = ('songs',)
选项 3
如果您想要一个舒适的 UI 而无需实施自定义页面或操作(不幸的是,它们完全是一团糟),您应该使用 StackedInline admin.
不过还是比较难。
首先,您需要在两个模型之间设置 through model. (I don't think inlines are possible with auto-generated many-to-many models.) It's basucally your many-to-many。类似的东西:
class ScheduleSongNM(models.Model):
song = models.ForeignKey("Song", null=False)
schedule = models.ForeignKey("Schedule", null=False)
告诉您的 Schedule
模型使用您的自定义通过模型:
class Schedule(models.Model):
songs = models.ManyToManyField(Song, through="ScheduleSongNM")
现在为 ScheduleSongNM
创建一个内联管理员:
class ScheduleSongInline(admin.StackedInline):
model = ScheduleSongNM
fields = ["song"]
autocomplete_fields = ["song"] # select2 works here too
最后,告诉您的 Schedule
管理员它现在有内联:
@admin.register(Schedule)
class ScheduleAdmin(admin.ModelAdmin):
...
inlines = [ScheduleSongInline]
...
也许我漏掉了什么(很明显我还没有测试过),但我想你已经明白了。最后,您会在 Schedule
管理界面中看到一个看起来像这样的框(加上歌曲名称的自动完成):