DateTimeField não aparece no sistema de administração

87

Por que meu campo "data" não aparece no sistema de administração?

No meu arquivo admin.py eu tenho

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

e o modelo de avaliação tem um campo chamado "data" que se parece com este

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

No entanto, dentro do sistema de administração, o campo não mostra, embora editableesteja definido como True.

Alguém tem alguma ideia?

maluco
fonte

Respostas:

55

Eu acredito que a razão está com o auto_now_addcampo.

Desde esta resposta :

Qualquer campo com o atributo auto_now definido também herdará editable = False e, portanto, não aparecerá no painel de administração.

Também mencionado nos documentos :

Conforme implementado atualmente, definir auto_now ou auto_now_add como True fará com que o campo tenha editable = False e blank = True definido.

Isso faz sentido, já que não há razão para ter o campo editável se ele for sobrescrito com a data e hora atual quando o objeto for salvo.

Shawn Chin
fonte
31
Embora com certeza você deva ser capaz de editar auto_now_addpor meio do administrador depois que a entrada for criada?
Christopher Orr
68
Você também deve ser capaz de simplesmente exibi- lo na interface de administração, mesmo que não seja editável.
Brad
1
Consulte a resposta de @hunger abaixo para saber como exibi-lo como um campo somente leitura na interface de administração.
guival
1
Faz sentido ter um campo editável se o campo for iniciado apenas na criação de um objeto (auto_now_add = True).
sergzach
206

Se você realmente deseja ver a data no painel de administração, pode adicionar readonly_fieldsem admin.py :

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

admin.site.register(Rating,RatingAdmin)

Qualquer campo que você especificar será adicionado por último, após os campos editáveis. Para controlar o pedido, você pode usar as fieldsopções.

Informações adicionais estão disponíveis nos documentos do Django .

Fome
fonte
33
ESTA é a verdadeira resposta !!
GreenAsJade de
4
se você estipular um, fieldsvocê também terá que colocar seu campo nisso, então você precisaria dele readonly_fieldse, fieldscaso contrário, o campo não apareceria.
Bjorn
Eu só queria observar que isso também se aplica se você estiver usando fieldsets, apenas encontrei esse problema hoje.
Kevin Brown,
1
Isso fará com que o campo apareça apenas quando clicarmos e abrirmos uma entrada específica. Se você quiser que o campo fique visível na própria
exibição de
1
Observe que não tenho certeza do porquê, mas isso não parece funcionar para DateTimeFields com auto_now_add=Trueno Django 1.9. Uma (espécie de) solução alternativa é adicioná-los à list_displaytupla. Editar: Funcionará se você também adicionar seu campo fieldscomo @BjornTipling mencionado.
Taylor Edmiston
23

Hack principal:

Se você realmente precisa fazer isso (como eu), você sempre pode contornar isso definindo imediatamente o campo como "editável", definindo o campo da seguinte maneira:

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

Isso tornará o campo editável, para que você possa realmente alterá-lo. Parece funcionar bem, pelo menos com o mecanismo de apoio do mysql. Não posso dizer com certeza se outros armazenamentos de apoio tornariam esses dados imutáveis ​​no banco de dados e, portanto, causariam um problema quando a edição for tentada, então use com cuidado .

Brad
fonte
Nah, não faça isso, use a solução readonly_fields descrita por Hunger.
GreenAsJade de
2
@GreenAsJade: Uma justificativa seria bom.
mhsmith de
@mhsmith Racional para usar a solução do Hunger em vez disso: porque este é um grande hack e vem com "use com cautela", enquanto a solução do Hunger usa django da maneira que foi projetada para ser usada. Por que você arriscaria um grande hack quando você pode fazer o que precisa de uma forma legítima e com suporte?
GreenAsJade de
6
Esta solução de hack não é tão ruim. O único caso de uso para ele, entretanto, vejo é o teste - quando o testador precisa alterar a data.
jacoor
2
só um aviso: este hack atrapalhou as migrações para mim
damio
16

Dependendo de suas necessidades específicas e de quaisquer nuances na diferença de comportamento, você pode fazer o seguinte:

from django.utils.timezone import now

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

O campo padrão pode ser usado desta forma: 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.

Isso não define editável para False

orblivion
fonte
1
Eu usaria em from django.utils.timezone import nowvez de datetime.now, mas isso parece promissor.
amjoconn
Obrigado, eu mudei isso.
orblivion
Stackoverflow é incrível porque, algumas respostas fazem você perceber que você não fez a pergunta certa! Obrigado.
Samuel Dauzon
5

Pode ter a ver com o fato de auto_now_add ser verdadeiro. Talvez em vez desse parâmetro para capturar a data na adição, você possa substituir o método de salvamento do modelo para inserir a data e hora quando o id é nulo.

class Rating(models.Model):

    ....
    def save(self, *args, **kwargs)
        if not self.id: 
            self.date = datetime.datetime.now()
Joe J
fonte
Se você fez isso, não há razão para definir o campo como auto_now
FallenAngel
Não tenho certeza por que o downvote; o primeiro link que Shawn Chin fornece indica uma abordagem semelhante.
Joe J
Essa é uma alternativa sensata, supondo que auto_nownão seja usado e editable=False. +1
Shawn Chin
3

Se você deseja que qualquer campo seja visível na lista de todas as suas entradas (quando você clica em um modelo na equipe de administração) e não quando você abre essa entrada em particular, então -

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

admin.site.register(Rating, RatingAdmin)

'nome' sendo o seu campo principal ou qualquer outro campo que você deseja exibir no painel de administração.

Desta forma, você pode especificar todas as colunas que deseja ver.

Jyotman Singh
fonte
0

Você não pode fazer isso, verifique a documentação

auto_now e auto_now_add são campos não editáveis e você não pode substituí-los ...

Anjo caído
fonte