No Django, como se poderia utilizar a vista genérico update_object do Django para editar as formas de modelos herdados?

votos
0

No Django, dado excertos de uma aplicação animais likeso:

Um animais / models.py com:

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()

E um animais / 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+)$', 'create_update.update_object', dict),
)

Como pode-se usar views genéricas para editar cão e / ou gato usando a mesma forma?

Ou seja, a forma de objecto que é passado para animais / animal_form.html será animal, e, assim, não irá conter qualquer dos detalhes específicos para a classes de cão e gato derivado. Como eu poderia ter Django passar automaticamente um formulário para a classe filha para animais / animals_form.html ?

Aliás, estou usando Djangosnippets # 1031 para a gestão ContentType, então animal teria um método chamado as_leaf_class que retorna a classe derivada.

Claramente, pode-se criar formulários para cada classe derivada, mas isso é um monte de duplicação desnecessária (como os modelos serão todos genérica - essencialmente `form`.`as_p`).

Aliás, é melhor assumir que animal será, provavelmente, uma das várias classes de base relacionado com o mesmo problema, então uma solução ideal seria genérico.

Agradeço antecipadamente a ajuda.

Publicado 17/10/2008 em 19:16
fonte usuário
Em outras línguas...                            


2 respostas

votos
1

Tudo bem, aqui está o que eu fiz, e parece trabalhar e ser um design sensível (embora eu estar a ser corrigido!).

Em uma biblioteca central (por exemplo mysite.core.views.create_update), eu escrevi um decorador:

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

E em animais / views.py, eu tenho:

from mysite.core.views.create_update import update_object_as_child

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

E em animais / urls.py, eu tenho:

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

Agora eu só preciso de uma função de edição única para cada classe base, que é trivial para criar com um decorador.

Espero que alguém descobre que útil, e eu ficaria encantado de ter feedback.

Respondeu 18/10/2008 em 20:40
fonte usuário

votos
0

AFAICT, cães e gatos estão em diferentes tabelas de banco de dados, e talvez não há nenhuma mesa Animal. mas você está usando um padrão de URL para todos. em algum lugar, você precisa escolher entre cada.

Eu usaria um patter URL diferente para cães e gatos, tanto chamaria 'create_update.update_object'; mas usando um diferente dictpara cada. um com 'model':Doge outro com'model':Cat

ou talvez você quer uma única tabela, onde cada registro pode ser um gato ou um cão? Eu não acho que você pode usar modelos herdados por isso.

Respondeu 17/10/2008 em 19:51
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more