2009-06-20 21 views
14

Chciałbym dodać pole do modelu bazy danych Django FlatPage, ale tak naprawdę nie wiem jak to rozszerzyć bez edytowania oryginalnej aplikacji.Dodaj funkcjonalność do Django FlatPages bez zmiany oryginalnej aplikacji Django

Co chcę zrobić, to dodać następujące pola do modelu


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

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

Jak mogę dodać to do modelu FlatPage?

góry dzięki

Odpowiedz

20

Twoje podejście jest w porządku - po prostu nie widać wyniku, ponieważ stary model strony jest zarejestrowany w panelu administratora, a nowy nie. Oto, co można zrobić w nowej aplikacji admin.py (używając mniej dwuznaczne nazewnictwo niż to, co masz powyżej):

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) 

Oczywiście istnieje kilka rzeczy się tu dzieje, ale najważniejsze jest model FlatPage jest niezarejestrowany, a na jego miejsce jest rejestrowany model ExtendedFlatPage.

+0

Wielkie dzięki! Sądzę, że tego właśnie szukałem. –

+8

Należy pamiętać, że to podejście nie będzie działać z domyślnym FlatpageFallbackMiddleware - zwróci instancje oryginalnego modelu Flatpage, a nie rozszerzenia. Musisz więc napisać własną wersję lub użyć własnego adresu URL/widoku. Ponadto masz teraz dwie tabele, w których tak naprawdę tylko jedna jest potrzebna, co skutkuje mniej wydajnymi zapytaniami.Podsumowując, polecam napisać własną aplikację płaską od zera lub używając metody class_prepared do monkeypatch w polu, zamiast używać dziedziczenia. –

7

I sposób w swoim poście nie działa, ponieważ ...?

Jeśli z jakiegoś powodu naprawdę trzeba bawić z wbudowanym klasy FlatPage i edytować go dynamicznie, można podłączyć do class_prepared sygnału:

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

Edytuj

Oto jak to zrobić z klasą: przygotowano:

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) 

Umieść to w, powiedzmy, "signals.py" w tym samym katalogu, co plik settings.py, i dodaj 'sygnały' do top (jest to ważne, aby upewnić się, że program obsługi sygnału zostanie zainstalowany w czasie) listę INSTALLED_APPS.

Jednak to nadal nie spowoduje wyświetlenia pola w Admin, ponieważ istnieje niestandardowa klasa ModelAdmin dla FlatPages, która wyraźnie wymienia pola. Po zarejestrowaniu się w aplikacji flatpages musisz ją gdzieś wyrejestrować (admin.site.unregister) i zarejestrować swój własny ModelAdmin.

+0

Pole nie pojawia się w panelu administratora? Nie rozumiem dlaczego. To jest problem –

+0

Cóż, nie ma powodu, żeby był pokazywany w administratorze dla wbudowanej klasy Django - nie zmodyfikowałeś go! Jeśli utworzysz własną FlatPage, w oddzielnej aplikacji musisz zarejestrować swoją nową klasę u administratora. Jeśli nie chcesz tego zrobić, możesz przejść do metody class_prepared, ale zakłada to dość dobrą znajomość języka Python. – oggy

+0

Hmm ok, myślałem, że będę w stanie monkeypatch oryginalnej klasy FlatPage, więc faktycznie pojawi się w admin bez tworzenia nowej aplikacji (i modeli). Czy możesz podać przykład metody przygotowanej przez class_prepared? –

Powiązane problemy