Dans Django, comment utiliser la vue générique update_object de Django pour modifier les formulaires de modèles hérités?

StackOverflow https://stackoverflow.com/questions/213237

Question

À Django, des extraits d'une application animaux likeso:

Un animaux / modèles.py avec:

from django.db import models
from django.contrib.contenttypes.models import ContentType

class Animal(models.Model):
  content_type = models.ForeignKey(ContentType,editable=False,null=True)
  name = models.CharField()

class Dog(Animal):
  is_lucky = models.BooleanField()

class Cat(Animal):
  lives_left = models.IntegerField()

Et un animaux / urls.py :

from django.conf.urls.default import *

from animals.models import Animal, Dog, Cat

dict = { 'model' : Animal }

urlpatterns = (
  url(r'^edit/(?P<object_id>\d+)

Comment utiliser des vues génériques pour éditer Dog et / ou Cat en utilisant le même formulaire?

I.e. L'objet formulaire qui est transmis à animaux / animal_form.html sera Animal, et ne contiendra donc aucun des détails des classes dérivées Dog et Cat. Comment pourrais-je faire en sorte que Django transmette automatiquement un formulaire pour la classe enfant à animal / animals_form.html ?

D'ailleurs, j'utilise Djangosnippets n ° 1031 pour la gestion de ContentType, pour qu'Animal puisse avoir une méthode nommée as_leaf_class qui renvoie la classe dérivée.

Il est clair que vous pouvez créer des formulaires pour chaque classe dérivée, mais il s’agit de beaucoup de duplications inutiles (car les modèles seront tous génériques - essentiellement {{form.as_p}}).

Incidemment, il est préférable de supposer qu'Animal sera probablement l'une des nombreuses classes de base non liées ayant le même problème. Une solution idéale serait donc générique.

Merci d'avance pour votre aide.

, 'create_update.update_object', dict), )

Comment utiliser des vues génériques pour éditer Dog et / ou Cat en utilisant le même formulaire?

I.e. L'objet formulaire qui est transmis à animaux / animal_form.html sera Animal, et ne contiendra donc aucun des détails des classes dérivées Dog et Cat. Comment pourrais-je faire en sorte que Django transmette automatiquement un formulaire pour la classe enfant à animal / animals_form.html ?

D'ailleurs, j'utilise Djangosnippets n ° 1031 pour la gestion de ContentType, pour qu'Animal puisse avoir une méthode nommée as_leaf_class qui renvoie la classe dérivée.

Il est clair que vous pouvez créer des formulaires pour chaque classe dérivée, mais il s’agit de beaucoup de duplications inutiles (car les modèles seront tous génériques - essentiellement {{form.as_p}}).

Incidemment, il est préférable de supposer qu'Animal sera probablement l'une des nombreuses classes de base non liées ayant le même problème. Une solution idéale serait donc générique.

Merci d'avance pour votre aide.

Était-ce utile?

La solution

Très bien, voici ce que j'ai fait et cela semble fonctionner et être un modèle sensé (même si je me fais corriger!).

Dans une bibliothèque principale (par exemple, mysite.core.views.create_update), j'ai écrit un décorateur:

from django.contrib.contenttypes.models import ContentType
from django.views.generic import create_update

def update_object_as_child(parent_model_class):
   """
   Given a base models.Model class, decorate a function to return  
   create_update.update_object, on the child class.

   e.g.
   @update_object(Animal)
   def update_object(request, object_id):
      pass

  kwargs should have an object_id defined.
  """

  def decorator(function):
      def wrapper(request, **kwargs):
          # may raise KeyError
          id = kwargs['object_id']

          parent_obj = parent_model_class.objects.get( pk=id )

          # following http://www.djangosnippets.org/snippets/1031/
          child_class = parent_obj.content_type.model_class()

          kwargs['model'] = child_class

          # rely on the generic code for testing/validation/404
          return create_update.update_object(request, **kwargs)
      return wrapper

  return decorator

Et dans animals / views.py, j'ai:

from mysite.core.views.create_update import update_object_as_child

@update_object_as_child(Animal)
def edit_animal(request, object_id):
  pass

Et chez les animaux / urls.py, j'ai:

urlpatterns += patterns('animals.views',
  url(r'^edit/(?P<object_id>\d+)

Maintenant, je n'ai besoin que d'une fonction d'édition unique pour chaque classe de base, ce qui est simple à créer avec un décorateur.

J'espère que quelqu'un trouvera cela utile et je serais ravi de recevoir vos commentaires.

, 'edit_animal', name="edit_animal"), )

Maintenant, je n'ai besoin que d'une fonction d'édition unique pour chaque classe de base, ce qui est simple à créer avec un décorateur.

J'espère que quelqu'un trouvera cela utile et je serais ravi de recevoir vos commentaires.

Autres conseils

AFAICT, les chats et les chiens sont sur des tables DB différentes, et peut-être qu’il n’ya pas de table Animal. mais vous utilisez un modèle d'URL pour tous. quelque part, vous devez choisir entre chacun.

J'utiliserais un modèle d'URL différent pour les chats et les chiens, les deux appelleraient 'create_update.update_object' ; mais en utilisant un dict différent pour chacun. une avec 'modèle': Dog et l'autre avec 'modèle': Cat

ou vous voulez peut-être une seule table où chaque enregistrement peut être un chat ou un chien? Je ne pense pas que vous puissiez utiliser les modèles hérités pour cela.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top