2009-06-20 10 views
14

Je voudrais ajouter un champ au modèle de base de données Django FlatPage, mais je ne sais pas vraiment comment l'étendre sans modifier l'application d'origine.Ajouter des fonctionnalités à Django FlatPages sans modifier l'application Django d'origine

Ce que je veux faire est d'ajouter le champ suivant le modèle:


from django.db import models 
from django.contrib.flatpages.models import FlatPage as FlatPageOld 

class FlatPage(FlatPageOld): 
    order = models.PositiveIntegerField(unique=True) 

Comment puis-je obtenir de l'ajouter au modèle flatpage?

Merci à l'avance

Répondre

20

Votre approche est correcte - vous ne voyez tout simplement pas le résultat car l'ancien modèle flatpage est enregistré dans l'admin et le nouveau ne l'est pas. Voici ce que vous pourriez faire dans votre nouvelle admin.py de l'application (en utilisant la dénomination moins ambiguë que ce que vous avez ci-dessus):

from django.contrib import admin 
from django.contrib.flatpages.admin import FlatPageAdmin 
from django.contrib.flatpages.forms import FlatpageForm 
from django.contrib.flatpages.models import FlatPage 

from models import ExtendedFlatPage 

class ExtendedFlatPageForm(FlatpageForm): 
    class Meta: 
     model = ExtendedFlatPage 

class ExtendedFlatPageAdmin(FlatPageAdmin): 
    form = ExtendedFlatPageForm 
    fieldsets = (
     (None, {'fields': ('url', 'title', 'content', 'sites', 'order')}), 
    )  

admin.site.unregister(FlatPage) 
admin.site.register(ExtendedFlatPage, ExtendedFlatPageAdmin) 

Évidemment, il y a quelques choses qui se passent ici, mais surtout le modèle flatpage est étant non enregistré et le modèle ExtendedFlatPage est enregistré à sa place.

+0

Merci beaucoup! Je suppose que c'est ce que je cherchais. –

+8

Gardez à l'esprit que cette approche ne fonctionnera pas avec FlatpageFallbackMiddleware par défaut - elle retournera des instances du modèle Flatpage original, pas votre extension. Vous devrez donc écrire votre propre version ou utiliser votre propre URL/vue. En outre, vous disposez maintenant de deux tables dont une seule est nécessaire, ce qui entraîne des requêtes moins efficaces.Dans l'ensemble, je recommande d'écrire votre propre application flatpage à partir de zéro, ou en utilisant l'approche class_prepared pour monkeypatch le champ, plutôt que d'utiliser l'héritage. –

7

Et la méthode dans votre post ne fonctionne pas parce que ...?

Si pour une raison quelconque, vous vraiment besoin de jouer avec la classe builtin flatpage et modifier dynamiquement, vous pouvez accrocher au signal class_prepared:

http://docs.djangoproject.com/en/dev/ref/signals/#class-prepared

Modifier

Voici comment vous le feriez avec un class_prepared:

from django.db.models.signals import class_prepared 
from django.db import models 

def alter_flatpages(sender, **kwargs): 
    if sender.__module__ == 'django.contrib.flatpages.models' and sender.__name__ == 'FlatPage': 
     order = models.IntegerField() 
     order.contribute_to_class(sender, 'order') 

class_prepared.connect(alter_flatpages) 

Mettez ceci dans, par exemple, 'signals.py' dans le même répertoire que votre settings.py, et ajoutez 'signals' au top (ceci est important, pour s'assurer que le gestionnaire de signal est installé à temps) de la liste INSTALLED_APPS. Toutefois, le champ ne s'affiche toujours pas dans Admin, car il existe une classe ModelAdmin personnalisée pour FlatPages qui répertorie explicitement les champs. Ainsi, une fois enregistré dans l'application flatpages, vous devrez l'annuler (admin.site.unregister) et enregistrer votre ModelAdmin.

+0

Le champ n'apparaît pas dans l'admin? Je ne comprends pas pourquoi. C'est le problème –

+0

Eh bien, il n'y a aucune raison que cela apparaisse dans l'admin de la classe Django intégrée - vous ne l'avez pas modifié! Si vous créez votre propre FlatPage, dans une application séparée, vous devez enregistrer votre nouvelle classe avec l'administrateur. Si vous ne voulez pas faire cela, vous pouvez utiliser la méthode class_prepared, mais cela suppose une bonne connaissance de Python. – oggy

+0

Hmm ok, je pensais que je serais capable de monkeypatch la classe FlatPage d'origine afin qu'il apparaisse dans l'admin sans créer une nouvelle application (et modèles). Pouvez-vous donner un exemple de la méthode class_prepared? –