programing

Django Admin의 모델 히스토리에 연결

nasanasas 2020. 9. 16. 07:46
반응형

Django Admin의 모델 히스토리에 연결


설정:

  • 사용자가 데이터베이스에 개체를 만든 다음 원하는만큼 돌아가서 편집 할 수있는 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 ).


관리자의 변경 내역 로그는에 정의 되어 있으며 표준 클래스 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 신호


예제 코드

여보세요,

I recently hacked in some logging to an "update" view for our server inventory database. I figured I would share my "example" code. The function which follows takes one of our "Server" objects, a list of things which have been changed, and an action_flag of either ADDITION or CHANGE. It simplifies things a wee bit where ADDITION means "added a new server." A more flexible approach would allow for adding an attribute to a server. Of course, it was sufficiently challenging to audit our existing functions to determine if a changes had actually taken place, so I am happy enough to log new attributes as a "change".

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."

참고URL : https://stackoverflow.com/questions/987669/tying-in-to-django-admins-model-history

반응형