В Django, как можно использовать общий вид update_object в Django для редактирования форм унаследованных моделей? - PullRequest
0 голосов
/ 17 октября 2008

В Джанго, приведены выдержки из приложения животные likeso:

A animal / 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),
)

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

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

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

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

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

Заранее спасибо за помощь.

Ответы [ 2 ]

1 голос
/ 18 октября 2008

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

В основной библиотеке (например, 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

А у животных / 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"),
)

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

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

0 голосов
/ 17 октября 2008

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

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

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

...