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

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

Pergunta

Em Django, dadas trechos de uma aplicação animais likeso:

A 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 se pode usar views genéricas para editar cão e / ou gato usando a mesma forma?

i. O form objeto que é passado para animais / animal_form.html será Animal, e, portanto, não irá conter qualquer uma das especificidades para as classes derivadas do cão e gato. Como eu poderia ter Django passar automaticamente um formulário para a classe criança a animais / animals_form.html ?

A propósito, estou usando Djangosnippets # 1031 para a gestão ContentType, então animal faria ter um método chamado as_leaf_class , que retorna a classe derivada.

É claro, 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.

Agradecemos antecipadamente pela ajuda.

Foi útil?

Solução

Tudo bem, aqui está o que eu fiz, e parece trabalho 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ó precisa 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.

Outras dicas

AFAICT, gatos e cães 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 utilizando um dict diferente para cada. um com 'model':Dog e 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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top