DateTimeField không hiển thị trong hệ thống quản trị


88

Tại sao trường "ngày tháng" của tôi không xuất hiện trong hệ thống quản trị?

Trong tệp admin.py của tôi, tôi có

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

và mô hình Xếp hạng có một trường được gọi là "ngày" trông giống như sau

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

Tuy nhiên trong hệ thống quản trị, trường không hiển thị, mặc dù editableđược đặt thành True.

Có ai có ý kiến ​​gì không?

Câu trả lời:


56

Tôi tin rằng lý trí nói dối với auto_now_addlĩnh vực này.

Từ câu trả lời này :

Bất kỳ trường nào có tập thuộc tính auto_now cũng sẽ kế thừa editable = False và do đó sẽ không hiển thị trong bảng quản trị.

Cũng được đề cập trong tài liệu :

Như được triển khai hiện tại, việc đặt auto_now hoặc auto_now_add thành True sẽ khiến trường có bộ editable = False và blank = True.

Điều này có ý nghĩa, vì không có lý do gì để trường có thể chỉnh sửa nếu nó sẽ bị ghi đè bằng ngày giờ hiện tại khi đối tượng được lưu.


31
Mặc dù chắc chắn bạn sẽ có thể chỉnh sửa auto_now_addthông qua quản trị viên sau khi mục nhập lần đầu tiên được tạo?
Christopher Orr

68
Bạn cũng có thể đơn giản hiển thị nó trong giao diện quản trị, ngay cả khi nó không thể chỉnh sửa được.
Brad

1
Vui lòng tham khảo câu trả lời của @hunger bên dưới để biết cách hiển thị nó dưới dạng trường chỉ đọc trong giao diện quản trị.
guival

1
Sẽ có ý nghĩa khi có một trường có thể chỉnh sửa nếu trường đó chỉ được kích hoạt khi tạo đối tượng (auto_now_add = True).
sergzach

207

Nếu bạn thực sự muốn xem ngày trong bảng điều khiển quản trị, bạn có thể thêm readonly_fieldsvào admin.py :

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

admin.site.register(Rating,RatingAdmin)

Bất kỳ trường nào bạn chỉ định sẽ được thêm vào cuối cùng sau các trường có thể chỉnh sửa. Để kiểm soát thứ tự, bạn có thể sử dụng các fieldstùy chọn.

Thông tin bổ sung có sẵn từ tài liệu Django .


33
Đây là câu trả lời thực sự !!
GreenAsJade

4
nếu bạn quy định một, fieldsbạn cũng phải đặt trường của bạn vào đó, vì vậy bạn sẽ cần nó cả trong readonly_fieldsfieldsnếu không thì trường sẽ không hiển thị.
Bjorn

Tôi chỉ muốn lưu ý rằng điều này cũng được áp dụng nếu bạn đang sử dụng fieldsets, vừa gặp sự cố này hôm nay.
Kevin Brown

1
Điều này sẽ làm cho trường chỉ xuất hiện khi chúng ta nhấp và mở một mục nhập cụ thể. Nếu bạn muốn trường hiển thị trong chính chế độ xem danh sách thì stackoverflow.com/a/34966908/4440874
Jyotman Singh

1
Lưu ý rằng tôi không chắc tại sao nhưng điều này dường như không hoạt động đối với DateTimeFields với auto_now_add=TrueDjango 1.9. Một cách giải quyết (loại) là thêm chúng vào list_displaybộ giá trị thay thế. Chỉnh sửa: Nó sẽ hoạt động nếu bạn cũng thêm trường của mình vào fieldsnhư @BjornTipling đã đề cập.
Taylor Edmiston

23

Hack chính:

Nếu bạn thực sự cần làm điều này (như tôi làm), bạn luôn có thể hack xung quanh nó bằng cách ngay lập tức thiết lập trường thành "có thể chỉnh sửa" xác định trường như sau:

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

Điều này sẽ làm cho trường có thể chỉnh sửa, vì vậy bạn thực sự có thể thay đổi nó. Nó có vẻ hoạt động tốt, ít nhất là với công cụ hỗ trợ mysql. Tôi không thể nói với certian liệu các cửa hàng sao lưu khác có làm cho dữ liệu này trở nên bất biến trong cơ sở dữ liệu và do đó gây ra sự cố khi cố gắng chỉnh sửa hay không, vì vậy hãy thận trọng khi sử dụng .


Không, đừng làm điều này, hãy sử dụng giải pháp readonly_fields được mô tả bởi Hunger.
GreenAsJade

2
@GreenAsJade: Một lý do hợp lý sẽ tốt.
mhsmith

@mhsmith Cơ sở lý do để sử dụng giải pháp của Hunger thay vì giải pháp này: bởi vì đây là một cuộc tấn công lớn và đi kèm với "sử dụng thận trọng", nên giải pháp của Hunger sử dụng django theo cách nó được thiết kế để sử dụng. Tại sao bạn lại có nguy cơ bị hack lớn khi bạn có thể làm những gì bạn cần một cách hợp pháp và được hỗ trợ?
GreenAsJade

6
Giải pháp hack này không phải là xấu. Tuy nhiên, trường hợp sử dụng duy nhất cho nó là thử nghiệm - khi người thử nghiệm cần thay đổi ngày.
jacoor

2
chỉ là một cảnh báo: vụ hack này đã làm xáo trộn quá trình di cư đối với tôi
damio

16

Tùy thuộc vào nhu cầu cụ thể của bạn và bất kỳ sắc thái khác biệt nào trong hành vi, bạn có thể làm như sau:

from django.utils.timezone import now

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

Trường mặc định có thể được sử dụng theo cách này: 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.

Điều này không đặt có thể chỉnh sửa thành False


1
Tôi sẽ sử dụng from django.utils.timezone import nowthay vì datetime.now, nhưng điều này có vẻ hứa hẹn.
amjoconn

Cảm ơn, tôi đã thay đổi nó.
orblivion

Stackoverflow thật tuyệt vời bởi vì, một số câu trả lời khiến bạn nhận ra rằng mình đã không hỏi đúng câu hỏi! Cảm ơn bạn.
Samuel Dauzon

5

Nó có thể phải làm với auto_now_add là true. Có lẽ thay vì tham số đó để ghi lại ngày trên add, bạn có thể ghi đè phương thức lưu mô hình để chèn ngày giờ khi id là null.

class Rating(models.Model):

    ....
    def save(self, *args, **kwargs)
        if not self.id: 
            self.date = datetime.datetime.now()

Nếu bạn đã làm, thì không có lý do gì để xác định lĩnh vực như auto_now
FallenAngel

Không chắc tại sao downvote; liên kết đầu tiên mà Shawn Chin cung cấp chỉ ra một cách tiếp cận tương tự.
Joe J

Đó là một sự thay thế hợp lý, giả sử auto_nowkhông được sử dụng và editable=False. +1
Shawn Chin

3

Nếu bạn muốn bất kỳ trường nào hiển thị trong danh sách tất cả các mục nhập của mình (khi bạn nhấp vào một mô hình trong người quản trị) chứ không phải khi bạn mở mục nhập cụ thể đó thì -

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

admin.site.register(Rating, RatingAdmin)

'name' là trường chính của bạn hoặc bất kỳ trường nào khác mà bạn muốn hiển thị trong bảng điều khiển quản trị.

Bằng cách này, bạn có thể chỉ định tất cả các cột bạn muốn xem.


0

Bạn không thể làm điều đó, hãy kiểm tra tài liệu

auto_nowauto_now_add đều là các trường không thể chỉnh sửa và bạn không thể ghi đè chúng ...

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.