I'm currently developing a project which uses django-polymorphic
models to handle
different kinds of content/apps in the same way. A simplified example
of this would
be as follows:
class Base(PolymorphicModel):
def render(self):
return ''
class ModelA(Base):
content = models.TextField()
def render(self):
return self.content
class ModelB(Base):
def render(self):
return do_something()
If I use admin.site.register on all the models, I'm perfectly able to
edit ModelA, ModelB
and Base as expected, but what I actually want to do is just register
Base and be able
to edit instances of ModelA and ModelB.
I know this is not something you can easily implement in the admin
site (how do you
create a new instance of either ModelA of ModelB from the Base admin
page), but I
think it is an interesting concept.
Is there anyone who has some ideas about implementing this? I might be
able to patch
something together myself. Please say how you feel about this. Is it
something worth
spending time on of is it a horrible idea?
Yours faithfully,
Hidde-Jan
> If I use admin.site.register on all the models, I'm perfectly
> able to> edit ModelA, ModelB and Base as expected, but
> what I actually want to do is just register
> Base and be able to edit instances of ModelA and ModelB.
When (in your example) editing the Base table, the admin most likely
uses polymorphic querysets with ModelA/ModelB objects, but always uses
the same Base-class ModelForm to edit them.
Using a custom ModelAdmin class for Base, I get this far:
class BaseAdmin(admin.ModelAdmin):
form = BaseAdminForm
class BaseAdminForm(forms.ModelForm):
class Meta:
model = Base
admin.site.register(Base, BaseAdmin)
see also:
http://docs.djangoproject.com/en/dev/ref/contrib/admin/#adding-custom-validation-to-the-admin
What seems missing for a solution is the possibility to dynamically
specify different forms in BaseAdmin, depending on the specific object
that the form will be used for.
This:
class BaseAdmin(admin.ModelAdmin):
form = BaseAdminForm
would somehow need to be more dynamic, like this:
class BaseAdmin(admin.ModelAdmin):
def get_form(self, object_to_be_edited): # created dynamic form
class here and return it
"object_to_be_edited" would be of type Base, ModelA or ModelB and
get_form() would dynamically create the correct form for the object
object_to_be_edited.
Of course this would need a patch to the admin app, but probably a
small one.
Alternatively, perhaps BaseAdminForm could be convinced to do this
(without patching admin).
I did not look deep enough into this yet, however.
> (how do you create a new instance of either ModelA of ModelB
> from the Base admin page), but I think it is an interesting concept.
Yes, the creation of new objects with the admin is an additional issue
here. A way to select the desired sub-model would need to be added to
the admin's "add object" button. I don't know if the admin app's API
already allows such additions.
> Is it something worth spending time on of is it a horrible idea?
The concept for admin-integration you outlined here looks very sound
to me; it's probably the best approach to integrate polymorphic
objects into the admin.
I personally did not use the admin for polymorphic models yet, but I
will probably look somewhat deeper into this topic as well.
If you come up with any kind of solution, please let us know.
Kind Regards,
Bert Constantin