Как можно использовать общее представление update_object в Django для редактирования форм унаследованных моделей?

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

Вопрос

В Django приведены выдержки из приложения животные вот так:

А животные/models.py с:

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

И животные/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),
)

Как можно использовать общие представления для редактирования собак и/или кошек, используя одну и ту же форму?

Т.е.А форма объект, который передается животные/animal_form.html будет Animal и, следовательно, не будет содержать никаких особенностей производных классов Dog и Cat.Как я мог бы заставить Django автоматически передавать форму дочернему классу животное/animals_form.html?

Я, кстати, использую Джангосниппеты #1031 для управления ContentType, поэтому у Animal будет метод с именем as_leaf_class который возвращает производный класс.

Очевидно, что можно создавать формы для каждого производного класса, но это будет довольно много ненужного дублирования (поскольку все шаблоны будут универсальными — по сути, {{ form.as_p }}).

Кстати, лучше всего предположить, что Animal, вероятно, будет одним из нескольких несвязанных базовых классов с одной и той же проблемой, поэтому идеальным решением будет обобщенное решение.

Заранее благодарю за помощь.

Это было полезно?

Решение

Хорошо, вот что я сделал, и, похоже, это работает и представляет собой разумный дизайн (хотя меня могут поправить!).

В основной библиотеке (например.mysite.core.views.create_update), я написал декоратор:

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

А в Animals/views.py у меня есть:

from mysite.core.views.create_update import update_object_as_child

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

И в животные/urls.py у меня есть:

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

Теперь мне нужна только уникальная функция редактирования для каждого базового класса, которую легко создать с помощью декоратора.

Надеюсь, кто-то найдет это полезным, и я буду рад получить обратную связь.

Другие советы

AFAICT, кошки и собаки находятся в разных таблицах БД, и, возможно, таблицы Animal нет.но вы используете один шаблон URL для всех.где-то нужно выбирать между каждым.

Я бы использовал разные шаблоны URL-адресов для кошек и собак, оба вызывали бы 'create_update.update_object';но используя другой dict для каждого.один с 'model':Dog и другой с 'model':Cat

или, может быть, вам нужна одна таблица, где каждая запись может быть кошкой или собакой?я не думаю, что для этого можно использовать унаследованные модели.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top