2009-05-25 12 views
2

Je sais comment définir les valeurs initiales d'un formulaire à partir de la vue. Mais comment puis-je laisser une vue générique définir les valeurs initiales à un formulaire? Je peux écrire une vue wrapper pour la vue générique, mais je n'ai toujours pas accès à l'instanciation de l'objet formulaire.Comment laisser la vue générique de Django utiliser un formulaire avec des valeurs initiales?

L'objectif spécifique que j'essaie de réaliser est de permettre à un utilisateur de créer un nouvel objet, en utilisant la vue générique create_object. Cependant, je voudrais définir un champ de l'objet 'user' à l'utilisateur actuellement connecté, accessible uniquement en tant que request.user. Comment le formulaire peut-il être initialisé pour avoir ce champ?

Éditer: Je suis tombé sur __new__. Pourrait-il appeler son propre constructeur avec des arguments par défaut?

Merci beaucoup.

+0

Je ne comprends pas vraiment le but de ceci, mais avez-vous regardé les variables template_name et extra_content? Mais sérieusement, pourquoi ne pas écrire une page/formulaire html et arrêter d'essayer de trouver des façons génériques de faire cela. Si vous avez besoin de définir une valeur particulière (comme l'utilisateur) dans un formulaire, vous êtes déjà en train de programmer pour un cas très spécifique. – drozzy

Répondre

4

Malheureusement, vous ne pouvez pas obtenir ce comportement via la vue générique create_object de Django; vous devrez écrire le vôtre. Cependant, c'est plutôt simple.

Pour commencer, vous devez créer une nouvelle classe de forme, comme ceci:

from django import forms 
class MyForm(forms.ModelForm): 
    class Meta: 
     model = MyModel # model has a user field 

Ensuite, vous pourrez créer une vue comme celui-ci:

from django.shortcuts import render_to_response 
from django.template import RequestContext 
from django.http import HttpResponseRedirect 
from django.contrib.auth.decorators import login_required 

@login_required 
def create_mymodel(request): 
    if request.method == 'POST': 
     # Get data from form 
     form = MyForm(request.POST) 
     # If the form is valid, create a new object and redirect to it. 
     if form.is_valid(): 
      newObject = form.save() 
      return HttpResponseRedirect(newObject.get_absolute_url()) 
    else: 
     # Fill in the field with the current user by default 
     form = MyForm(initial={'user': request.user}) 
    # Render our template 
    return render_to_response('path/to/template.html', 
     {'form': form}, 
     context_instance=RequestContext(request)) 
+0

Merci. Je le savais déjà, mais le point de vue générique est si tentant qu'il ne pouvait pas fonctionner avec les valeurs initiales. –

+0

Je suis d'accord: les vues génériques sont géniales, mais si vous voulez définir les valeurs par défaut, c'est un cauchemar. Et je suis entièrement d'accord avec le post de Carl Meyer. –

3

Vous pouvez le faire en un wrapper de vue générique en construisant dynamiquement une classe de formulaire et en la passant à la vue générique, mais cette guérison est probablement pire que la maladie. Il suffit d'écrire votre propre point de vue, et attendez avec impatience this pour atterrir.

0

Si vous voulez toutes les fonctionnalités de la vue générique, vous pouvez simplement créer une nouvelle vue générique en utilisant l'original comme modèle.

Par exemple:

def create_object_with_initial(request, model=None, template_name=None, 
    template_loader=loader, extra_context=None, post_save_redirect=None, 
    login_required=False, context_processors=None, form_class=None, initial=None): 

if extra_context is None: extra_context = {} 
if login_required and not request.user.is_authenticated(): 
    return redirect_to_login(request.path) 

model, form_class = get_model_and_form_class(model, form_class) 
if request.method == 'POST': 
    form = form_class(request.POST, request.FILES) 
    if form.is_valid(): 
     new_object = form.save() 

     msg = ugettext("The %(verbose_name)s was created successfully.") %\ 
           {"verbose_name": model._meta.verbose_name} 
     messages.success(request, msg, fail_silently=True) 
     return redirect(post_save_redirect, new_object) 
else: 
    print "creating", form_class, " with initial data ", initial 
    form = form_class(initial=initial) 

# Create the template, context, response 
if not template_name: 
    template_name = "%s/%s_form.html" % (model._meta.app_label, model._meta.object_name.lower()) 
t = template_loader.get_template(template_name) 
c = RequestContext(request, { 
    'form': form, 
}, context_processors) 
apply_extra_context(extra_context, c) 
return HttpResponse(t.render(c)) 

Ceci est copié à partir /site-packages/django/views/generic/create_update.py avec des lignes seulement 3 et 21 changements pour incorporer les données initiales.

Utilisez ensuite comme on pouvait s'y attendre:

object_info = { 
'model': YourModel, 
'initial': {'data' : 'Initial Value'}, 
'template_name': 'template.html' 
} 

url(r'^path/$', 
    login_required(create_object_with_initial), 
    object_info, 
    name='url_name'), 

Cela devrait fonctionner.

Questions connexes