2010-09-01 6 views
4

Lorsque j'affiche le ToolBoxEditForm, il utilise un champ de sélection multiple. Mais ce que je veux, c'est un formulaire qui permet à l'utilisateur de modifier chaque outil qu'il a dans la boîte à outils sous forme de champ de texte. Je n'arrive pas à comprendre comment faire cela avec le champ many-to-many.Comment modifier un champ de sélection multiple en plusieurs champs de saisie pour un cas plusieurs-à-plusieurs?

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',) 

Répondre

2

les plus sexy Solution

Vous pouvez utiliser l'un des outils de autocommplete jquery décrits ici: Facebook style JQuery autocomplete plugin

ensuite sous la forme:

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',) 

Vous auriez à comprendre comment modifier le JavaScript afin que de nouveaux éléments puissent être saisis (c'est-à-dire pas seulement sur es déjà dans la base de données).

Solution alternative

C'est un peu ce que le inline formsets ont été créés pour, si Narendra's solution fonctionnera.

Quelque chose comme:

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, 
    }) 

Non pas que ce formulaire est uniquement pour l'édition des éléments dans la boîte à outils. Si vous voulez que l'utilisateur puisse éditer d'autres aspects de la boîte à outils - par exemple, son nom ou sa description - vous devez créer un formulaire séparé et les afficher tous les deux dans les mêmes balises <form></form>.

+0

C'est exactement ce que j'ai fini par faire !! J'ai utilisé l'approche jquery. Cela fonctionne magnifiquement. Merci! – adeleinr

0

Je ne suis pas sûr, puisque non testé, mais voici la logique va.

  1. Créer formset pour ToolBoxEditForm via formset_factory
  2. Modifier le type de champ tool_name à CharField
  3. certain nombre de lignes dans formset précisément le nombre d'objets outil disponible dans db
  4. Pass initiales à Formset constructeur remplir les zones de texte tool_name.

    # TODO: les données suivantes doivent être générées dynamiquement

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

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

Vous n'êtes pas sûr de la partie validation. Ici, nous plaçons tool_name comme valeur pour la zone de texte. Pendant la validation, le formulaire peut s'attendre à l'ID (car il est supposé être listbox). Mais, vous pouvez gérer cela aussi.

pour plus d'informations sur formset se réfèrent: http://docs.djangoproject.com/en/dev/topics/forms/formsets/

Questions connexes