설정:
- 사용자가 데이터베이스에 개체를 만든 다음 원하는만큼 돌아가서 편집 할 수있는 Django 애플리케이션을 개발 중입니다.
- Django의 관리 사이트는 관리 사이트를 통해 개체에 적용된 변경 내역을 유지합니다.
질문:
- 사용자가 "콘텐츠"에 대한 변경 내역을 볼 수 있도록 내 응용 프로그램을 관리 사이트의 변경 내역에 연결하려면 어떻게해야합니까?
답변:
관리자 기록은 다른 Django 앱과 같은 앱일뿐입니다. 단, 관리자 사이트의 특별한 위치는 예외입니다.
모델은 django.contrib.admin.models.LogEntry에 있습니다.
사용자가 변경하면 다음과 같이 로그에 추가합니다 (contrib / admin / options.py에서 뻔뻔하게 도난 당함).
from django.contrib.admin.models import LogEntry, ADDITION
LogEntry.objects.log_action(
user_id = request.user.pk,
content_type_id = ContentType.objects.get_for_model(object).pk,
object_id = object.pk,
object_repr = force_unicode(object),
action_flag = ADDITION
)
object
물론 변경된 객체는 어디에 있습니까 ?
이제 다니엘의 대답을보고 그에 동의합니다. 상당히 제한적입니다.
제 생각에 더 강력한 접근 방식은 그의 저서 Pro Django 에서 Marty Alchin의 코드를 사용하는 것입니다 ( 263 페이지에서 시작 하는 Historical Records 유지 참조 ). 이 접근 방식을 구현하고 확장 하는 애플리케이션 django-simple-history 가 있습니다 ( docs here ).
from django.utils.encoding import force_unicode
'force_unicode'에 대한
관리자의 변경 내역 로그는에 정의 되어 있으며 표준 클래스 django.contrib.admin.models
에는 history_view
메서드가 ModelAdmin
있습니다.
하지만 특별히 영리하지 않고 관리자와 밀접하게 연결되어 있으므로 아이디어를 위해 이것을 사용하고 앱을위한 고유 한 버전을 만드는 것이 가장 좋습니다.
이 질문이 오래되었다는 것을 알고 있지만 오늘 (Django 1.9) 현재 Django의 역사 항목은이 질문의 날짜보다 더 강력합니다. 현재 프로젝트에서는 최근 기록 항목을 가져와 탐색 모음에서 드롭 다운에 넣어야했습니다. 이것이 내가 한 방법이며 매우 간단합니다.
*views.py*
from django.contrib.admin.models import LogEntry, ADDITION, CHANGE, DELETION
def main(request, template):
logs = LogEntry.objects.exclude(change_message="No fields changed.").order_by('-action_time')[:20]
logCount = LogEntry.objects.exclude(change_message="No fields changed.").order_by('-action_time')[:20].count()
return render(request, template, {"logs":logs, "logCount":logCount})
위의 코드 스 니펫에서 볼 수 있듯이 LogEntry 모델 (django.contrib.admin.models.py는 django 1.9에있는 위치)에서 기본 쿼리 세트를 만들고 변경 사항이없는 항목을 제외하고 순서를 지정합니다. 작업 시간과 지난 20 개의 로그 만 표시합니다. 카운트만으로 다른 아이템도 받고 있어요. LogEntry 모델을 살펴보면 Django가 필요한 데이터 조각을 가져 오기 위해 사용한 필드 이름을 볼 수 있습니다. 내 특정 경우에 내 템플릿에서 사용한 내용은 다음과 같습니다.
*template.html*
<ul class="dropdown-menu">
<li class="external">
<h3><span class="bold">{{ logCount }}</span> Notification(s) </h3>
<a href="{% url 'index' %}"> View All </a>
</li>
{% if logs %}
<ul class="dropdown-menu-list scroller actionlist" data-handle-color="#637283" style="height: 250px;">
{% for log in logs %}
<li>
<a href="javascript:;">
<span class="time">{{ log.action_time|date:"m/d/Y - g:ia" }} </span>
<span class="details">
{% if log.action_flag == 1 %}
<span class="label label-sm label-icon label-success">
<i class="fa fa-plus"></i>
</span>
{% elif log.action_flag == 2 %}
<span class="label label-sm label-icon label-info">
<i class="fa fa-edit"></i>
</span>
{% elif log.action_flag == 3 %}
<span class="label label-sm label-icon label-danger">
<i class="fa fa-minus"></i>
</span>
{% endif %}
{{ log.content_type|capfirst }}: {{ log }}
</span>
</a>
</li>
{% endfor %}
</ul>
{% else %}
<p>{% trans "This object doesn't have a change history. It probably wasn't added via this admin site." %}</p>
{% endif %}
</li>
</ul>
이미 언급 한 내용을 추가하려면 다음과 같은 다른 리소스를 참조하세요.
(1) 저는 관리자 기록에 '연결'되어 실제로 추가되는 django-reversion 이라는 앱으로 작업 해 왔습니다 . 보기 좋은 곳이 될 샘플 코드를 원한다면.
(2) 자신의 히스토리 기능을 롤링하기로 결정한 경우 django는 각 히스토리 객체에 대한 post_save와 같이 앱을 처리하도록 구독 할 수있는 신호를 제공합니다. 기록 로그 항목이 저장 될 때마다 코드가 실행됩니다. Doc : Django 신호
여보세요,
최근에 서버 인벤토리 데이터베이스의 "업데이트"보기에 대한 로깅을 해킹했습니다. 내 "예제"코드를 공유 할 것이라고 생각했습니다. 다음 함수는 "서버"객체 중 하나, 변경된 항목 목록 및 ADDITION 또는 CHANGE의 action_flag를 사용합니다. ADDITION이 "새 서버 추가"를 의미하는 작업을 약간 단순화합니다. 보다 유연한 접근 방식을 사용하면 서버에 속성을 추가 할 수 있습니다. 물론 변경 사항이 실제로 발생했는지 확인하기 위해 기존 기능을 감사하는 것은 충분히 어려웠으므로 새 속성을 "변경 사항"으로 기록 할 수있어 기쁩니다.
from django.contrib.admin.models import LogEntry, User, ADDITION, CHANGE
from django.contrib.contenttypes.models import ContentType
def update_server_admin_log(server, updated_list, action_flag):
"""Log changes to Admin log."""
if updated_list or action_flag == ADDITION:
if action_flag == ADDITION:
change_message = "Added server %s with hostname %s." % (server.serial, server.name)
# http://dannyman.toldme.com/2010/06/30/python-list-comma-comma-and/
elif len(updated_list) > 1:
change_message = "Changed " + ", ".join(map(str, updated_list[:-1])) + " and " + updated_list[-1] + "."
else:
change_message = "Changed " + updated_list[0] + "."
# http://stackoverflow.com/questions/987669/tying-in-to-django-admins-model-history
try:
LogEntry.objects.log_action(
# The "update" user added just for this purpose -- you probably want request.user.id
user_id = User.objects.get(username='update').id,
content_type_id = ContentType.objects.get_for_model(server).id,
object_id = server.id,
# HW serial number of our local "Server" object -- definitely change when adapting ;)
object_repr = server.serial,
change_message = change_message,
action_flag = action_flag,
)
except:
print "Failed to log action."