Django ModelForm Проверять пользовательское автозаполнение для M2M вместо уродливого Multi-Select - PullRequest
3 голосов
/ 07 октября 2009

Учитывая следующие модели (вырублено для понимания):

class Venue(models.Model):
    name = models.CharField(unique=True)

class Band(models.Model):
    name = models.CharField(unique=True)

class Event(models.Model):    
    name = models.CharField(max_length=50, unique=True)       
    bands = models.ManyToManyField(Band) 
    venue = models.ForeignKey(Venue)
    start = models.DateField()
    end = models.DateField()

Область администратора отлично подходит для того, что я делаю, но я бы хотел немного открыть сайт, чтобы некоторые пользователи могли добавлять новые события. Для публичных частей у меня есть несколько «административных» полей в этих моделях, которые я не хочу, чтобы публика видела (что достаточно легко исправить).

Моя конкретная проблема, однако, заключается в изменении отображения выбора ManyToMany при создании нового события. Поскольку количество полос, которые можно перечислить для события, не следует отправлять в виде поля множественного выбора, я хотел бы использовать автозаполнение, которое обрабатывает кратные значения (например, поле «Теги» в StackOverflow!).

У меня эта часть работает , и она правильно заполняет скрытый ввод с Band.id, разделенным запятыми для значения. Однако , я не могу понять, как собрать Django для проверки, используя ModelForms , и каким-то образом также проверить выбор 'Bands'.

В идеале я хочу выполнить автоматическое заполнение, как теги здесь, в StackOverflow, и отправлять выбранные идентификаторы полос в виде какой-либо строки с разделителями - все это, позволяя Django проверять существование пропущенных полос и т. Д., Как если бы я оставил Раздражающий список множественного выбора на месте.

Нужно ли создавать собственный тип поля автозаполнения для формы или модели и использовать его? Есть ли что-то еще, что я пропускаю?

Я видел некоторые существующие виджеты автозаполнения, но я действительно очень хочу использовать свой собственный код автозаполнения, поскольку он уже настроен, и некоторые из них выглядят немного запутанными.

Здесь было намного больше текста / объяснений, но я сократил, потому что я избегаю Wall Of Text. Если я пропустил важные вещи, дайте мне знать.

Ответы [ 2 ]

1 голос
/ 07 октября 2009

Трудно сказать, не зная точно, что делает ваш код автозаполнения, но пока он отправляет идентификаторы полос, как они будут отправлены с <select>, ModelForm должен проверять их как обычно.

По сути, ваша строка POST должна выглядеть так:

name=FooBar2009&bands=1&bands=3&bands=4&venue=7&start=...

Самый простой способ сделать это - использовать Javascript для добавления (и удаления) скрытого поля ввода для каждой полосы, введенной с именем band и идентификатором полосы в качестве значения. Затем, когда пользователь отправляет форму, браузер позаботится о публикации нужного материала, и ModelForm проверит ее.

0 голосов
/ 01 декабря 2009

Используя подключенный плагин jquery для автозаполнения,

На стороне клиента у меня есть что-то вроде этого:

jQuery("#id_tags").autocomplete('/tagging_utils/autocomplete/tasks/task/', {
    max: 10,
    highlight: false,
    multiple: true,
    multipleSeparator: " ",
    scroll: true,
    scrollHeight: 300,
    matchContains: true,
    autoFill: true,
}); 

Итак, у меня есть представление, которое возвращается, когда я набираю a:

http://skyl.org/tagging_utils/autocomplete/tasks/task/?q=a&limit=10&timestamp=1259652876009

Вы можете увидеть это представление здесь:

http://github.com/skyl/skyl.org/blob/master/apps/tagging_utils/views.py

Теперь, это будет немного сложно ... вы можете, кроме POST, затем в методе clean поля попытаться .get () на основе строк и вызвать ошибку проверки формы, если вы не можете получить это ... правильно, имя = ... уникальное = правда ... так что-то вроде (от макушки) ...:

def clean_bands(self):
    return Band.objects.filter( name__in = self.cleaned_data['bands'].split(' ') )

Вы также можете проверить каждую строку и вызвать ошибку формы, если с таким именем нет бэндов ... не уверены, что метод clean должен возвращать qs. Дайте мне знать, если это поможет, и вы хотите, чтобы я продолжил / уточнил.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...