2009-07-09 10 views
1

je reçois des données à partir de POST et valident via cet extrait standard:Modification de données dans un django ModelForm

entry_formset = EntryFormSet(request.POST, request.FILES, prefix='entries') 
if entry_formset.is_valid(): 
    .... 

Le ModelForm EntryFormSet remplace un widget champ de clé étrangère pour présenter un champ de texte. De cette façon, l'utilisateur peut entrer une clé existante (suggérée via une recherche en direct Ajax), ou entrer une nouvelle clé, qui sera ajoutée de manière transparente.

J'utilise ce bloc try-except pour tester si l'objet existe déjà, et si ce n'est pas le cas, je l'ajoute.

entity_name = request.POST['entries-0-entity'] 
try: 
    entity = Entity.objects.get(name=entity_name) 
except Entity.DoesNotExist: 
    entity = Entity(name=entity_name) 
    entity.slug = slugify(entity.name) 
    entity.save() 

Cependant, je dois maintenant obtenir ce entity de nouveau dans le entry_formset. Il pense que entries-0-entity est une chaîne de caractères (c'est comme ça que c'est arrivé); comment puis-je directement accéder à cette valeur du entry_formset et l'amener à prendre la référence d'objet à la place?

+0

La question n'est pas claire. Où se passe le second extrait de code? Il serait probablement utile si vous avez posté plus de votre point de vue. –

+0

Le deuxième extrait arrive directement dans le bloc 'if entry_formset.is_valid()'. –

+1

sans rapport avec votre question, quelle est la raison de ne pas utiliser Entity.objects.get_or_create (name = entity_name)? –

Répondre

2

Je suggère d'écrire une fonction d'usine auxiliaire pour votre jeu de formulaires afin que vous puissiez personnaliser le widget d'affichage en fonction des données. Quelque chose comme ce qui suit:

def make_entry_formset(initial_obj=None, custom_widget=forms.Textarea): 
    # these will be passed as keyword arguments to the ModelChoiceField 
    field_kwargs={'widget': custom_widget, 
        'queryset': Entity.objects.all()} 
    if initial_obj is not None: 
     field_kwargs.update({'initial': initial_obj}) 
    class _EntryForm(forms.ModelForm): 
     entity = forms.ModelChoiceField(**field_kwargs) 

     class Meta: 
      model = Entry 
    return modelformset_factory(Entry, form=_EntryForm) 

Puis dans votre code de vue, vous pouvez spécifier le widget que vous voulez et si vous souhaitez lier à un objet initial Entity. Pour le rendu initial du formset, où vous voulez juste un widget Textarea et pas d'autre choix initial, vous pouvez utiliser ceci:

formset_class = make_entry_formset(custom_widget=forms.Textarea) 
entry_formset = formset_class() 

Ensuite, si vous voulez le rendre à nouveau (après le bloc is_valid()) avec l'objet Entity déjà défini, vous pouvez utiliser ceci:

formset_class = make_entry_formset(initial_obj=entity, 
            custom_widget=forms.HiddenInput) 
entry_formset = formset_class(request.POST, request.FILES) 

vous pouvez utiliser un widget que vous aimez, bien sûr, mais en utilisant un HiddenInput empêcherait l'utilisateur final d'interagir avec ce domaine (que vous semblez vouloir se lier à la entity variable que vous avez recherché).

Questions connexes