2010-11-12 4 views
6

J'ai une application web django avec plusieurs utilisateurs qui se connectent et remplissent un formulaire.Django Enregistrer la progression inachevée sur le formulaire

Certains utilisateurs peuvent commencer à remplir un formulaire et ne possèdent pas les données requises (par exemple, un numéro de subvention) nécessaires pour valider le formulaire (et avant que nous puissions commencer à travailler dessus). Je veux qu'ils soient en mesure de remplir le formulaire et avoir une option pour enregistrer les informations partielles (un autre jour, ils peuvent se connecter et le compléter) ou soumettre l'information complète en cours de validation.

Actuellement j'utilise ModelForm pour tous les formulaires que j'utilise, et le modèle a des contraintes pour assurer des données valides (par exemple, le # de subvention doit être unique). Cependant, je veux qu'ils puissent sauvegarder ces données intermédiaires sans subir de validation. La solution à laquelle j'ai pensé semble plutôt inélégante et un-django-ey: créer un bouton "Save Partial Form" qui sauvegarde le dictionnaire POST le convertit en un fichier shelf et créer un modèle "SavedPartialForm" connectant l'utilisateur aux formulaires partiels enregistrés dans l'étagère. Est-ce que cela semble raisonnable? Existe-t-il un meilleur moyen de sauvegarder le dict POST directement dans la base de données? Ou est-ce un module complémentaire qui effectue cette sauvegarde partielle d'un formulaire (ce qui semble être une activité assez courante avec des formulaires Web)? Ma plus grande préoccupation avec ma méthode est que je veux être capable de faire automatiquement cette forme-autosave automatiquement (disons toutes les 10 minutes) dans une certaine méthode ajax/jquery sans réellement appuyer sur un bouton et envoyer la requête POST (par exemple, l'utilisateur n'est pas redirigé hors de la page lorsque la sauvegarde automatique est déclenchée). Je ne suis pas familier avec jquery et je me demande s'il serait possible de le faire.

+0

avez-vous réussi à obtenir ce fonctionnement? Pouvez-vous fournir une réponse détaillée sur la façon de le faire. Ce sera très utile pour les autres développeurs .. –

Répondre

5

Il existe une bonne solution dans Pro Django by Marty Alchin. En un mot, vous créez un autre modèle qui contient un hachage du formulaire, le champ de formulaire et la valeur enregistrée. Lors de la reprise, il suffit de charger selon le formulaire en fonction de son hash.

1

Le problème est que vous avez plusieurs formulaires.

Partiel. Incomplet. Achevée. Prêt pour ça. Prêt pour ça.

En effet, vous avez un formulaire par étape d'un flux de travail.

Rien à redire à cela.

  1. Déterminez où vous êtes dans le flux de travail.

  2. Remplir et présenter le formulaire pour l'étape suivante.

Les formulaires peuvent hériter les uns des autres pour enregistrer les méthodes de validation répétées.

+0

Merci. C'est utile et c'est une bonne façon de voir les choses. Je me demande toujours si cela peut être incompatible avec des formes partielles/incomplètes à enregistrement automatique toutes les dix minutes environ avec une sorte de code jQuery. –

+0

@jimbob: Jamais. Le point est d'avoir un formulaire qui correspond à l'étape actuelle du flux de travail. S'ils ne peuvent pas renseigner les données appropriées pour leur étape du flux de travail, le formulaire n'est pas valide. S'ils ont rempli suffisamment pour cette étape, le formulaire est valide. Si elles veulent en remplir plus, vous devez parcourir les formulaires pertinents jusqu'à ce que vous rattrapiez ce qu'ils ont entré. –

2

avant enreg:

for field in form.fields: 
    form.fields[field].required = False 

alors:

form.save() 
0

Placez le suivant dans votre formulaire __init__

for field in form.fields: 
    form.fields[field].required = False 

Par exemple:

class MySexyForm(Form): 
    def __init__(self, *args, **kwargs): 
     super(MySexyForm, self).__init__(*args, **kwargs) 
     for field in self.fields: 
      self.fields[field].required = False 

appellent ensuite:

form = MySexyForm(...) 
form.save() 

Cependant, vous devrez vous assurer que votre méthode clean() peut gérer tous les attributs manquants en vérifiant certaines conditions si elles existent dans cleaned_data. Par exemple, si une autre validation de champ de formulaire repose sur customer_id mais que votre formulaire partiel n'en a pas spécifié un, alors customer_id ne sera pas dans les données nettoyées.

S'il s'agit d'une forme de modèle, vous pouvez vérifier si la valeur était dans cleaned_data et revenir à instance.field si elle manquait, par exemple;

def clean(self): 
    inst = self.instance 
    customer_id_new = self.cleaned_data.get('customer_id', None) 
    customer_id_old = getattr(self.instance, 'customer_id') if inst else None 
    customer_id = customer_id_new if customer_id_new else customer_id_old 

Rappelez-vous que la valeur nouvelle valeur sera presque certainement pas dans le même format que l'ancienne valeur, par exemple customer_id pourrait effectivement être un RelatedField sur l'instance de modèle, mais un pk int sur les données de formulaire. Encore une fois, vous devrez gérer ces différences de type dans votre propre.

Il s'agit d'un domaine où les formulaires Django manquent cruellement.

Questions connexes