Как изменить поле множественного выбора на несколько полей ввода для случая «многие ко многим»? - PullRequest
4 голосов
/ 01 сентября 2010

Когда я отображаю ToolBoxEditForm, он использует поле множественного выбора.Но мне нужна форма, которая позволяет пользователю редактировать каждый инструмент, который он имеет на панели инструментов, как текстовое поле.Я не могу понять, как это сделать с помощью поля «многие ко многим».

class Tool(models.Model):
    tool_name = models.CharField(unique=True, max_length=200)
......

class ToolBox(models.Model):
    tools = models.ManyToManyField(Tool,max_length=300)

class ToolBoxEditForm (ModelForm):
    tools = ???
    class Meta:
      model = ToolBox
      exclude  = ('user', 'popularity',)

Ответы [ 2 ]

2 голосов
/ 13 октября 2010

Самое сексуальное решение

Вы можете использовать один из описанных здесь инструментов автозаполнения jquery: Плагин автозаполнения JQuery в стиле Facebook

Затем в форме:

class ToolBoxEditForm (ModelForm):
    tools = forms.CharField(widget=forms.Textarea, required=False)

    def clean_tools(self):
        tool_data = self.cleaned_data.get('tools',None)
        tools = []
        #here, a comma is used a delim, so it's not allowed in the tool name.
        for td in tool_data.split(','): 
            t, _ = Tool.objects.get_or_create(name=td)
            tools.append(t)
        return tools

    class Meta:
      model = ToolBox
      exclude  = ('user', 'popularity',)

Вы должны выяснить, как изменить JavaScript, чтобы можно было вводить новые элементы (т.е. не только те, которые уже есть в базе данных).

Альтернативное решение

Этовроде того, для чего были созданы встроенные наборы форм , поэтому решение Нарендры будет работать.

Что-то вроде:

from django.forms.models import inlineformset_factory

def manage_toolbox(request, toolbox_id):
    toolbox = Toolbox.objects.get(pk=toolbox_id)
    ToolInlineFormSet = inlineformset_factory(Toolbox, Tool)
    if request.method == "POST":
        formset = ToolInlineFormSet(request.POST, request.FILES, instance=toolbox)
        if formset.is_valid():
            formset.save()
            # Do something.
    else:
        formset = ToolInlineFormSet(instance=toolbox)
    return render_to_response("manage_toolbox.html", {
        "formset": formset,
    })

Не то чтобы эта форматолько для редактирования элементов в наборе инструментов.Если вы хотите, чтобы пользователь мог редактировать другие аспекты Панели инструментов - скажем, его имя или описание - вы должны создать отдельную форму и вывести их в одинаковые теги <form></form>.

0 голосов
/ 02 сентября 2010

Я не уверен, так как не проверял, но вот логика идет.

  1. Создание набора форм для ToolBoxEditForm с помощью formset_factory
  2. Изменить тип поля tool_name на CharField
  3. Установить количество строк в наборе точно в соответствии с количеством объектов Tool, доступных в db
  4. Передать инициалы конструктору набора форм для заполнения текстовых полей tool_name.

    # TODO: следующие данные должны генерироваться динамически

    initial_data = [{'tool_name': u'first_tool_name ',}, {'tool_name': u'second_tool_name ',}]

    formset = ToolBoxFormSet (extra = 0, initial = initial_data)

Не уверен насчет части проверки. Здесь мы помещаем tool_name в качестве значения для текстового поля. Во время проверки форма может ожидать идентификатор (потому что он должен быть списком). Но вы можете справиться и с этим.

для получения дополнительной информации о форме набора см .: http://docs.djangoproject.com/en/dev/topics/forms/formsets/

...