In Django, wie könnte man Djangos update_object allgemeine Ansicht zu bearbeiten Formen erblicher Modelle verwenden?
-
03-07-2019 - |
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.
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.