2016-11-22 1 views
0

J'ai la vue sur la base de classe suivante que je veux utiliser pour rendre un formset et valider quand il est soumis par une méthode post:django rendre et valider formset en classe vue sur la base (ListView)

formset rend parfaitement. Lorsque je soumets le formulaire je peux lire le formset et le vérifier pour les erreurs. dans la méthode post de cette classe ->errors = backorder_formset.errors

Si je trouve des erreurs dans le formset, je voudrais rendre la vue, mais cette fois avec l'instance formset, que j'ai lue depuis POST. Quand j'appelle forme ctx = self.get_context_data() dans la méthode post de la classe l'erreur suivante est soulevée de l'appel super(MissingProductsListView, self).get_context_data(*args, **kwargs): 'MissingProductsListView' object has no attribute 'object_list'

Il semble que la superclasse de Listview effectue cet appel: queryset = kwargs.pop('object_list', self.object_list)

Ma question est pourquoi je cours dans cette erreur? et comment est-ce que je pourrais rendre ce formset avec ses messages d'erreurs pour l'afficher dans le modèle après qu'il ait été posté? J'utilise Django 1.9.9

class MissingProductsListView(generic.ListView): 
    template_name = 'dashboard/purchaseorder/missing_products.html' 
    context_object_name = 'backorders' 
    model = BackOrder 

    def post(self, request, *args, **kwargs): 
     backorder_formset = BackOrderFormset(request.POST) 
     errors = backorder_formset.errors 

     if backorder_formset.is_valid(): 
      # <process form cleaned data> 
      return HttpResponseRedirect('/success/') 
     else: 
      ctx = self.get_context_data() 
      return self.render_to_response(ctx) 


    def accumulate_identical_products_from_backorders(self, back_order_list): 
     ... some code 
     return sorted_accumulated_dict.values() 

    def get_context_data(self, *args, **kwargs): 
     ctx = super(MissingProductsListView, self).get_context_data(*args, **kwargs) 
     ctx['title'] = _("Missing Products") 
     if self.request.POST: 
      ctx['back_order_formset'] = BackOrderFormset(self.request.POST) 
     else: 
      accumulated_backorders_per_product = self.accumulate_identical_products_from_backorders(BackOrder.objects.all()) 

      back_orders = BackOrderFormset(initial=[{'product_id': backorder_dict['product_id'], 
                'product': backorder_dict['title'], 
                'quantity': backorder_dict['quantity']} for backorder_dict in 
                accumulated_backorders_per_product]) 
      ctx['back_order_formset'] = back_orders 
     return ctx 

    def get_queryset(self): 
     .. some code 
     return backorder_list 
+0

avez-vous essayé d'utiliser 'try ... except'Je pense que vous pouvez le faire si vous avez un modèle de rendu d'erreur avec des captures de massage d'erreur par exception? –

Répondre

1

Regardez ici:

class BaseListView(MultipleObjectMixin, View): 
    """ 
    A base view for displaying a list of objects. 
    """ 
    def get(self, request, *args, **kwargs): 
     self.object_list = self.get_queryset() 
     allow_empty = self.get_allow_empty() 

     if not allow_empty: 
      # When pagination is enabled and object_list is a queryset, 
      # it's better to do a cheap query than to load the unpaginated 
      # queryset in memory. 
      if self.get_paginate_by(self.object_list) is not None and hasattr(self.object_list, 'exists'): 
       is_empty = not self.object_list.exists() 
      else: 
       is_empty = len(self.object_list) == 0 
      if is_empty: 
       raise Http404(_("Empty list and '%(class_name)s.allow_empty' is False.") % { 
        'class_name': self.__class__.__name__, 
       }) 
     context = self.get_context_data() 
     return self.render_to_response(context) 

Fondamentalement - vous avez manqué cette partie dans le gestionnaire POST:

self.object_list = self.get_queryset() 

Et pour être honnête - je ne suis pas Bien sûr, si c'est une bonne idée d'ajouter un message au ListView générique dans django. Cela ressemble plus à FormView - mais je peux me tromper ici.

+0

Je ne pouvais pas courir dans l'exception quand je rendais manuellement la page et lui transmettais manuellement le contexte comme ceci: 'else: return render (request, self.template_name, {'back_order_formset': backorder_formset})' . Votre suggestion en utilisant FormView au lieu de ListView évite l'erreur que je rencontrais et est une solution meilleure et plus propre, merci! – matyas