#python #django #administration #manytomanyfield
Вопрос:
У меня есть база данных с более чем 1000 песнями. У меня есть пользовательская модель «Расписание», которая принимает песни в качестве поля.
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-администрировании, который выглядит так. Я должен прокрутить и CTRL выбрать каждый из них, а затем добавить их.
Мне бы хотелось чего-то более практичного, где я мог бы выбирать, искать и т. Д.
Какие у меня есть варианты? Я не знаю, с чего начать поиски.
Комментарии:
1. Я предполагаю, что вы ищете действия администратора, которые могут позволить вам выполнять поиск и выбирать несколько вариантов, не теряя свой выбор, и реализовывать их все сразу. Взгляните на это https://docs.djangoproject.com/en/3.2/ref/contrib/admin/actions/
2. Спасибо за предложение, но я не уверен, как там использовать действия… Это означает, что когда я нажимаю «Расписания» на главной странице администрирования, я попадаю в список расписаний (там я могу использовать действия). Но на скриншоте я затем щелкнул по определенному расписанию из этого списка, и теперь я вижу список песен…
Ответ №1:
Вариант 1
Это удобно только в том случае, если у вас очень мало связанных предметов (несколько песен в расписании). Но это очень просто и будет лучше, чем то, что у вас есть сейчас. (django.contrib.admin поставляется со встроенным выбором 2.)
@admin.register(Schedule)
class ScheduleAdmin(admin.ModelAdmin):
...
autocomplete_fields = ("songs",)
Вариант 2
(upd: черт, сначала забыл об этом, это также очень просто и довольно эффективно)
Все выглядит нормально. Пригодный. Не особенно удобно. Но лучше, чем щелкать по материалу ctrl.
@admin.register(Schedule)
class ScheduleAdmin(admin.ModelAdmin):
...
filter_horizontal = ('songs',)
Вариант 3
Если вам нужен удобный пользовательский интерфейс без реализации пользовательских страниц или действий (которые, к сожалению, являются полным беспорядком), вам следует использовать администратора StackedInline.
Хотя это немного сложнее.
Сначала вам понадобится сквозная модель. (Я не думаю, что строки возможны с автоматически сгенерированными моделями «многие ко многим».) В основном это ваше соотношение «многие ко многим» между двумя моделями. Что-то вроде того:
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
администратора, которое выглядит примерно так (плюс автоматическое заполнение названий песен).:
Комментарии:
1. Вариант 2 идеально подходит! Он может легко искать и добавлять, намного лучше, чем бесконечный список, который у меня сейчас есть. Также я думаю, что вы имели в виду filter_horizontal = («песни»,) для моего конкретного случая. Спасибо!
2. @Angelo Когда в вашей базе данных будет много тысяч песен, а страница с «вариантом 2» будет загружаться вечно, вы рассмотрите «вариант 3», ха-ха-ха
3. Черт возьми! Это означает, что я закладываю эту страницу, чтобы вернуться, когда вся моя жизнь рухнет xD