2009-02-10 8 views
0

J'ai un formulaire django qui contient un dictionnaire de chaînes. J'ai donné au formulaire un bouton de soumission et un bouton de prévisualisation. Lorsque le bouton de prévisualisation est pressé après avoir entré des informations, un POST est envoyé, et les chaînes du dictionnaire sont récupérées automatiquement (je suppose que c'est fait en utilisant l'état de session ou quelque chose). C'est génial, exactement ce que je voulais. Le problème est que si je ne soumets pas le formulaire, alors faire un GET (c'est-à-dire parcourir la page avec le formulaire), entrer quelques informations et un aperçu, les informations qui ont été stockées dans le dictionnaire le premier aperçu est toujours là.Django - comment supprimer les résultats mis en cache des messages de formulaires précédents?

Comment effacer ces informations?

Voici ma forme:

class ListingImagesForm(forms.Form): 
#the following should be indented 
def clear_dictionaries(self): 
    self.statuses = {} 
    self.thumbnail_urls = {} 
    self.image_urls = {} 

statuses = {} 
thumbnail_urls = {} 
image_urls = {} 

valid_images = SortedDict() #from the django framework 
photo_0 = forms.ImageField(required=False, label='First photo') 
photo_1 = forms.ImageField(required=False, label='Second photo') 

def clean_photo_0(self): 
    return self._clean_photo("photo_0") 

def clean_photo_1(self): 
    return self._clean_photo("photo_1") 


def _clean_photo(self, dataName): 
    data = self.cleaned_data[dataName] 
    if data != None: 
     if data.size > max_photo_size: 
      raise forms.ValidationError("The maximum image size allowed is 500KB") 
     elif data.size == 0: 
      raise forms.ValidationError("The image given is empty.") 
     else: 
      self.valid_images[dataName] = data 
      self.statuses[dataName] = True 
      list_of_image_locs = thumbs.save_image_and_thumbs(data.name, data) 
      self.image_urls[dataName] = list_of_image_locs[0] 
      self.thumbnail_urls[dataName] = list_of_image_locs[1] 
    return data 

Et voici la vue:

@login_required 
def add(request): 
#the following should be indented 
preview = False 
added = False 
new_listing = None 
owner = None 

if request.POST: 
    form = GeneralListingForm(request.POST) 
    image_form = ListingImagesForm(request.POST, request.FILES) 

    if image_form.is_valid() and form.is_valid(): 
     new_listing = form.save(commit=False) 
     new_listing.owner = request.user.get_profile() 

     if request.POST.get('preview', False): 
      preview = True 
      owner = new_listing.owner 

     elif request.POST.get('submit', False): 
      new_listing.save() 
      for image in image_form.image_urls: 
       url = image_form.image_urls[image] 
       try: 
        new_image = Image.objects.get(photo=url) 
        new_image.listings.add(new_listing) 
        new_image.save() 
       except: 
        new_image = Image(photo=url) 
        new_image.save() 
        new_image.listings.add(new_listing) 
        new_image.save() 

      form = GeneralListingForm() 
      image_form = ListingImagesForm() 
      image_form.clear_dictionaries() 
      added = True 

else: 
    form = GeneralListingForm() 
    image_form = ListingImagesForm() 
    image_form.clear_dictionaries() 

return render_to_response('add_listing.html', {'form': form, 'image_form' : image_form, 
               'preview': preview, 'added': added, 
               'owner': owner, 'listing': new_listing, 
               'currentmaintab': 'listings', 
               'currentcategory': 'all'}, 
                     context_instance=RequestContext(request)) 

Je n'ai pas été la programmation avec django ou python tout aussi longtemps, de sorte que tous les pointeurs sur la fixation des une partie du code est la bienvenue :)

+0

Veuillez fournir un exemple de code avec le formulaire et les fonctions de vue. –

+0

Je suppose que vous ne comprenez pas exactement ce qui se passe ici. Utilisez-vous des vues génériques? Est-ce que le formulaire sous-classe 'ModelForm'? –

+0

Non, nous ne sous-classes modelform, et nous n'utilisons pas non plus des vues génériques –

Répondre

2

Ce code est cassé dans le concept; ça ne fera jamais ce que tu veux. Vos dictionnaires sont des attributs de classe de la classe ListingImagesForm. Cette classe est un global au niveau du module. Vous stockez donc un état dans une variable globale en mémoire dans un processus de serveur Web. Cet état est global pour tous les utilisateurs de votre application, pas seulement pour l'utilisateur qui a soumis le formulaire, et il persistera (de la même manière pour tous les utilisateurs) jusqu'à ce qu'il soit modifié ou effacé explicitement (ou jusqu'à ce que processus/fil différent dans un serveur Web de production).

[EDIT: J'ai utilisé "global" ici d'une manière peu claire. Les attributs de classe ne sont pas "globaux", ils sont encapsulés dans l'espace de noms de classe comme vous le souhaitez. Mais vous assignez des attributs à l'objet de la classe, pas aux instances de la classe (ce que vous feriez dans une méthode __init __()). L'objet de classe est un global de niveau module, et il n'a qu'un ensemble d'attributs. Chaque fois que vous les changez, vous les changez pour tout le monde. Si vous modifiez le code ci-dessus afin que vos trois dictionnaires soient initialisés dans la méthode __init __(), votre "problème" de données "en cache" disparaîtra; »

Vous devez repenser votre conception en sachant que Django ne gère pas« automagiquement »votre état d'une requête à l'autre. Tout votre état doit être explicitement passé via POST ou GET, ou explicitement enregistré dans une session. Les attributs de classe sur une classe Form doivent être évités sauf pour les informations de type configuration immuable, et les attributs d'instance ne sont utiles que pour garder une trace de l'état temporaire lors du traitement d'une requête unique. est créé à chaque demande).

+0

Ok - merci d'expliquer, je ne savais pas que les attributs de ListingImagesForm étaient globaux, je vais devoir chercher les règles d'encapsulation :) –

+0

Désolé d'être pas clair; Ce n'est pas vraiment un problème d'encapsulation, c'est la différence entre les attributs de classe et les attributs d'instance. Je vais ajouter une modification pour essayer de clarifier. –

+0

Merci d'avoir expliqué cela. Je suis content que django n'ait pas ce lol 'magique' –

Questions connexes