In Django, wie könnte man Djangos update_object allgemeine Ansicht zu bearbeiten Formen erblicher Modelle verwenden?

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

Frage

In Django, da Auszüge aus einer Anwendung Tiere likeso:

A Tiere / models.py mit:

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

Und ein Tiere / 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),
)

Wie eine generischen Ansichten verwenden kann, bearbeiten Hund und / oder Katze die gleiche Form mit?

d. Die Form Objekt, das zu übergeben Tiere / animal_form.html wird Tier sein, und somit wird keine der Besonderheiten für die abgeleiteten Klassen Hund und Katze enthält. Wie könnte ich habe Django automatisch ein Formular für das Kind Klasse übergeben zu Tier / animals_form.html

Im Übrigen bin ich mit Djangosnippets # 1031 für Contentmanagement, so Tier würde haben eine Methode mit dem Namen as_leaf_class , das die abgeleitete Klasse zurückgibt.

Natürlich könnte man Formulare für jede abgeleitete Klasse erstellen, aber das ist eine ganze Menge unnötiger Doppelarbeit. (Wie die Vorlagen alle generisch sein werden - im Wesentlichen {{form.as_p}})

Im übrigen ist es am besten davon ausgeht, dass Tier wahrscheinlich ein von mehreren unabhängigen Basisklassen mit dem gleichen Problem sein, so eine ideale Lösung wäre generisch.

Vielen Dank im Voraus für die Hilfe.

War es hilfreich?

Lösung

In Ordnung, hier ist das, was ich getan habe, und es scheint ein vernünftiges Design zu arbeiten und sein (obwohl ich zu korrigierenden stehen!).

In einer Kern-Bibliothek (z mysite.core.views.create_update), ich habe einen Dekorateur geschrieben:

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

Und bei Tieren / views.py, ich habe:

from mysite.core.views.create_update import update_object_as_child

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

Und bei Tieren / urls.py, ich habe:

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

Jetzt brauche ich nur eine einzigartige Editierfunktion für jede Basisklasse, die mit einem Dekorateur zu schaffen trivial ist.

Hope jemand findet, dass hilfreich, und ich würde sehr freuen, Feedback.

Andere Tipps

AFAICT, Katzen und Hunde sind auf verschiedene DB-Tabellen, und vielleicht gibt es kein Tier Tisch. aber Sie verwenden ein URL-Muster für alle. irgendwo müssen Sie zwischen den einzelnen wählen.

ich eine andere URL Rüttler für Katzen und Hunde verwenden würde, würden beide 'create_update.update_object' nennen; aber mit einem anderen dict für jeden. ein mit 'model':Dog und das andere mit 'model':Cat

oder vielleicht wollen Sie eine einzelne Tabelle, in der jeder Datensatz eine Katze oder ein Hund sein kann? Ich glaube nicht, können Sie vererbte Modelle für diese verwenden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top