DateTimeField nie wyświetla się w systemie administracyjnym

88

Dlaczego moje pole „data” nie pojawia się w systemie administracyjnym?

W moim pliku admin.py mam

from django.contrib import admin
from glasses.players.models import *
admin.site.register(Rating)

a model oceny zawiera pole o nazwie „data”, które wygląda następująco

date = models.DateTimeField(editable=True, auto_now_add=True)

Jednak w systemie administracyjnym pole nie jest wyświetlane, mimo że editablejest ustawione na True.

Czy ktokolwiek ma jakiś pomysł?

rozsiany
źródło

Odpowiedzi:

56

Uważam, że rozsądek leży w auto_now_addpolu.

Z tej odpowiedzi :

Każde pole z ustawionym atrybutem auto_now będzie również dziedziczyć editable = False i dlatego nie pojawi się w panelu administracyjnym.

Wspomniane również w dokumentach :

Jak obecnie zaimplementowano, ustawienie auto_now lub auto_now_add na True spowoduje, że pole będzie miało editable = False i blank = True.

Ma to sens, ponieważ nie ma powodu, aby pole było edytowalne, jeśli ma zostać nadpisane bieżącą datą i godziną, gdy obiekt jest zapisywany.

Shawn Chin
źródło
31
Czy z pewnością powinieneś móc edytować auto_now_addprzez administratora po utworzeniu wpisu?
Christopher Orr
68
Powinieneś także móc po prostu wyświetlić go w interfejsie administratora, nawet jeśli był nieedytowalny.
Brad
1
Zapoznaj się z odpowiedzią @hunger poniżej, aby dowiedzieć się, jak wyświetlić ją jako pole tylko do odczytu w interfejsie administratora.
guival
1
Możliwość edycji pola ma sens, jeśli jest ono inicjowane tylko przy tworzeniu obiektu (auto_now_add = True).
sergzach
206

Jeśli naprawdę chcesz zobaczyć datę w panelu administratora, można dodać readonly_fieldsw admin.py :

class RatingAdmin(admin.ModelAdmin):
    readonly_fields = ('date',)

admin.site.register(Rating,RatingAdmin)

Każde określone pole zostanie dodane jako ostatnie po polach edytowalnych. Aby kontrolować kolejność, możesz skorzystać z fieldsopcji.

Dodatkowe informacje są dostępne w dokumentacji Django .

Głód
źródło
33
TO jest prawdziwa odpowiedź !!
GreenAsJade
4
jeśli określisz a, fieldsmusisz również umieścić w tym swoje pole, więc potrzebujesz go zarówno w, jak readonly_fieldsiw fieldsprzeciwnym razie pole nie pojawi się.
Bjorn,
Chciałem tylko zauważyć, że dotyczyło to również sytuacji, w których używasz fieldsets, właśnie dzisiaj napotkałem ten problem.
Kevin Brown
1
To sprawi, że pole pojawi się tylko wtedy, gdy klikniemy i otworzymy konkretny wpis. Jeśli chcesz, aby pole było widoczne w samym widoku listy, wtedy stackoverflow.com/a/34966908/4440874
Jyotman Singh
1
Zauważ, że nie jestem pewien dlaczego, ale wydaje się, że to nie działa dla DateTimeFields z auto_now_add=TrueDjango 1.9. (W pewnym sensie) obejściem jest dodanie ich do list_displaykrotki. Edycja: zadziała, jeśli dodasz również swoje pole fieldsjako wspomniane @BjornTipling.
Taylor Edmiston,
23

Duży hack:

Jeśli naprawdę musisz to zrobić (tak jak ja), zawsze możesz się obejść, natychmiast ustawiając pole jako „edytowalne”, definiując pole w następujący sposób:

class Point(models.Model):
  mystamp=models.DateTimeField("When Created",auto_now_add=True)
  mystamp.editable=True

To sprawi, że pole będzie można edytować, więc będziesz mógł je zmienić. Wydaje się, że działa dobrze, przynajmniej z silnikiem kopii zapasowej mysql. Nie mogę powiedzieć dla certian, czy inne magazyny zapasowe uczyniłyby te dane niezmiennymi w bazie danych, a tym samym spowodowałyby problem podczas próby edycji, więc używaj ostrożnie .

Ćwiek
źródło
Nie, nie rób tego, użyj rozwiązania readonly_fields opisanego przez Hunger.
GreenAsJade
2
@GreenAsJade: Uzasadnienie byłoby miłe.
mhsmith
@mhsmith Rationale, aby zamiast tego użyć rozwiązania Hunger: ponieważ jest to poważny hack i wymaga „ostrożnego używania”, rozwiązanie Hunger wykorzystuje django w sposób, w jaki zostało zaprojektowane. Dlaczego miałbyś ryzykować poważny włamanie, skoro możesz zrobić to, czego potrzebujesz w legalny i wspierany sposób?
GreenAsJade
6
To rozwiązanie hakerskie nie jest takie złe. Jedynym przypadkiem użycia, jaki widzę, jest testowanie - kiedy tester musi zmienić datę.
jacoor
2
tylko ostrzeżenie: ten hack
zepsuł
16

W zależności od Twoich konkretnych potrzeb i wszelkich niuansów w zachowaniu możesz wykonać następujące czynności:

from django.utils.timezone import now

class MyModel(models.Model):
    date = models.DateTimeField(default=now)

Domyślne pole można wykorzystać w ten sposób: https://docs.djangoproject.com/en/dev/ref/models/fields/#default

The default value for the field. This can be a value or a callable object. If callable it will be called every time a new object is created.

To nie pozwala na edycję False

orblivion
źródło
1
Użyłbym from django.utils.timezone import nowzamiast datetime.now, ale wygląda to obiecująco.
amjoconn
Dzięki, zmieniłem to.
orblivion
Stackoverflow jest niesamowity, ponieważ niektóre odpowiedzi sprawiają, że zdajesz sobie sprawę, że nie zadałeś właściwego pytania! Dziękuję Ci.
Samuel Dauzon
5

Może mieć to związek z faktem, że auto_now_add jest prawdziwe. Być może zamiast tego parametru do przechwytywania daty dodania można zastąpić metodę zapisu modelu, aby wstawić datę i godzinę, gdy identyfikator ma wartość null.

class Rating(models.Model):

    ....
    def save(self, *args, **kwargs)
        if not self.id: 
            self.date = datetime.datetime.now()
Joe J.
źródło
Jeśli tak, to nie ma powodu, aby definiować pole jako auto_now
FallenAngel
Nie jestem pewien, dlaczego głosowano przeciw; pierwsze łącze, które podaje Shawn Chin, wskazuje na podobne podejście.
Joe J
To rozsądna alternatywa, zakładając, że auto_nownie jest używana i editable=False. +1
Shawn Chin
3

Jeśli chcesz, aby jakiekolwiek pole było widoczne na liście wszystkich twoich wpisów (po kliknięciu modelu w osobach administratora), a nie po otwarciu tego konkretnego wpisu, to -

class RatingAdmin(admin.ModelAdmin):
    list_display = ('name', 'date') 

admin.site.register(Rating, RatingAdmin)

„nazwa” to Twoje główne pole lub inne pole, które chcesz wyświetlić w panelu administracyjnym.

W ten sposób możesz określić wszystkie kolumny, które chcesz zobaczyć.

Jyotman Singh
źródło
0

Nie możesz tego zrobić, sprawdź dokumentację

auto_now i auto_now_add to pola nieedytowalne i nie można ich zastąpić ...

Upadły anioł
źródło