জ্যাঙ্গো অ্যাডমিনের মডেল ইতিহাসের সাথে তাল মিলিয়ে


96

সেটআপ:

  • আমি একটি জ্যাঙ্গো অ্যাপ্লিকেশন নিয়ে কাজ করছি যা ব্যবহারকারীদের ডাটাবেসে কোনও অবজেক্ট তৈরি করতে এবং তারপরে ফিরে গিয়ে যতটা ইচ্ছা তারা সম্পাদনা করতে পারে।
  • জ্যাঙ্গোর অ্যাডমিন সাইট অ্যাডমিন সাইটের মাধ্যমে বস্তুগুলিতে পরিবর্তনগুলির একটি ইতিহাস রাখে।

প্রশ্নটি:

  • আমি কীভাবে আমার অ্যাপ্লিকেশনটিকে অ্যাডমিন সাইটের পরিবর্তনের ইতিহাসে যুক্ত করতে পারি যাতে ব্যবহারকারীরা তাদের "সামগ্রীতে" পরিবর্তনের ইতিহাস দেখতে পান?

উত্তর:


137

অ্যাডমিনের ইতিহাস অন্য জ্যাঙ্গো অ্যাপ্লিকেশানের মতো কেবল একটি অ্যাপ্লিকেশন, ব্যতিক্রম অ্যাডমিন সাইটে বিশেষ স্থান নির্ধারণের সাথে।

মডেলটি jango.contrib.admin.models.LogEntry এ রয়েছে।

যখন কোনও ব্যবহারকারী পরিবর্তন করেন, লগটিতে এই জাতীয় যুক্ত করুন (অবদান / অ্যাডমিন / অপশনটি থেকে নির্লজ্জভাবে চুরি করা:

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বস্তু অবশ্যই পরিবর্তিত হয়।

এখন আমি ড্যানিয়েলের উত্তর দেখতে পেয়েছি এবং তার সাথে একমত হয়েছি, এটি বেশ সীমাবদ্ধ।

আমার মতে একটি শক্তিশালী পদ্ধতি হল মার্তি আলচিনের কাছ থেকে তাঁর প্রো প্রো জাজানো বইটিতে কোডটি ব্যবহার করা (দেখুন পৃষ্ঠা 263 থেকে শুরু হওয়া orতিহাসিক রেকর্ডগুলি রাখা )। একটি অ্যাপ্লিকেশন রয়েছে জাঙ্গো-সাদামাটা-ইতিহাস যা এই পদ্ধতির প্রয়োগ এবং প্রসারিত করে ( ডক্স এখানে )।


9
ভুলে যাবেন না: django.contrib.contenttyype.models থেকে ContentType আমদানি করে। এছাড়াও, ফোর্স_ ইউনিিকোড তাদের নিজস্ব ফাংশন।
সাকাবাকো

12
from django.utils.encoding import force_unicode'ফোর্স_ইনিকোড'
মিমার্স 151

17
যেহেতু এই প্রশ্নের উত্তর দেওয়া হয়েছিল, মার্টি আলচিনের দৃষ্টিভঙ্গিটি জ্যাঙ্গো-সাদামাটা-ইতিহাস নামে একটি অ্যাপ্লিকেশনটিতে খোলা উত্সাহিত এবং প্রসারিত হয়েছে ।
ট্রে হানার

4
এর নতুন বাড়িতে জ্যাঙ্গো-সহজ-ইতিহাস : মনে করা হয় github.com/treyhunner/django-simple-history অব আরো তথ্য django-simple-history.readthedocs.org/en/latest
Brutus

4
একটি ভাল পদ্ধতির djangopackages.com এ তুলনা গ্রিড যাচাই করতে পারে যেখানে জ্যাঙ্গো -সাধারণ-ইতিহাস এবং অন্যান্য সমাধানগুলি (যেমন ক্লিঞ্জারভিশন বা জ্যাঙ্গো-রিভার্শন) তুলনা করা হয়।
প্রথম

22

প্রশাসকের পরিবর্তনের ইতিহাস লগটি সংজ্ঞায়িত করা হয় django.contrib.admin.modelsএবং history_viewস্ট্যান্ডার্ড ModelAdminশ্রেণিতে একটি পদ্ধতি রয়েছে ।

এগুলি যদিও বিশেষত চালাক নয় এবং প্রশাসনের সাথে মোটামুটি দৃ .়ভাবে মিলিত হয়েছে, তাই আপনি কেবল এগুলি ধারণাগুলির জন্য ব্যবহার করতে এবং আপনার অ্যাপ্লিকেশানের জন্য নিজের সংস্করণ তৈরি করতে পারেন।


4
এটা কি এখনও সত্য?
ক্লিক করুন

12

আমি জানি এই প্রশ্নটি পুরানো, তবে আজ (জ্যাঙ্গো ১.৯) হিসাবে, জ্যাঙ্গোর ইতিহাসের আইটেমগুলি এই প্রশ্নের তারিখের চেয়ে বেশি শক্তিশালী। একটি বর্তমান প্রকল্পে, আমার সাম্প্রতিক ইতিহাসের আইটেমগুলি নেওয়া এবং এটিকে নাবার থেকে ছাড়ার দরকার ছিল। এইভাবে আমি এটি করেছি এবং খুব সোজা এগিয়ে ছিল:

*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})

উপরের কোড স্নিপেটে যেমন দেখা গেছে, আমি লগইন্ট্রি মডেল (django.contrib.admin.models.py যেখানে এটি জাঙ্গো ১.৯ এ অবস্থিত) থেকে একটি বেসিক ক্যোয়ারসেট তৈরি করছি এবং যেখানে কোনও পরিবর্তন জড়িত না এমন আইটেমগুলি বাদ দিয়ে, এর দ্বারা আদেশ দিয়েছি ক্রিয়া সময় এবং কেবল গত 20 লগ দেখায় log আমি শুধু গণনা সহ অন্য আইটেম পাচ্ছি। আপনি যদি লগএন্ট্রি মডেলটি দেখে থাকেন তবে জঞ্জো আপনার প্রয়োজনীয় ডেটার টুকরো টুকরো টুকরো টানতে ব্যবহার করতে যে ক্ষেত্রের নামগুলি ব্যবহার করেছেন তা দেখতে পাবেন। আমার নির্দিষ্ট ক্ষেত্রে, আমি আমার টেম্পলেটটিতে এটি ব্যবহার করেছি:

চূড়ান্ত পণ্যের চিত্রের লিঙ্ক

*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>

7

ইতিমধ্যে যা বলা হয়েছে তাতে যুক্ত করতে এখানে আপনার জন্য আরও কিছু সংস্থান রয়েছে:

(1) আমি জ্যাঙ্গো-রিভার্সন নামে একটি অ্যাপের সাথে কাজ করছি যা প্রশাসকের ইতিহাসের 'হুকস' দেয় এবং আসলে এতে যুক্ত হয়। আপনি যদি কিছু নমুনা কোড চান তবে এটি দেখার জন্য ভাল জায়গা হবে।

(২) আপনি যদি নিজের ইতিহাসের কার্যকারিতা রোল করার সিদ্ধান্ত নিয়ে থাকেন তবে জাঙ্গো এমন সংকেত সরবরাহ করে যা আপনি নিজের অ্যাপ্লিকেশনটির হ্যান্ডেলটি সাবস্ক্রাইব করতে পারতেন, উদাহরণস্বরূপ, প্রতিটি ইতিহাসের অবজেক্টের জন্য পোস্ট_সেভ করুন। আপনার কোডটি প্রতিবার ইতিহাসের লগ এন্ট্রি সংরক্ষণ করা হবে। ডক: জ্যাঙ্গো সিগন্যাল


4
আমি দৃ strongly ়ভাবে জাঙ্গো-বিপরীতের বিরুদ্ধে সুপারিশ করব। ধারণা হিসাবে এটি একটি দুর্দান্ত ধারণা, তবে বাস্তবায়নটি ভয়াবহ। আমি এটি একটি প্রোডাকশন সাইটে ব্যবহার করেছি এবং এটি একটি দুঃস্বপ্ন। এটি প্রথমে দুর্দান্ত কাজ করেছে, তবে শেষ পর্যন্ত আমি জানতে পেরেছিলাম যে অ্যাপটি মোটেও স্কেলেবল নয়, তাই আধা ঘন ঘন পরিবর্তনগুলির সাথে যে কোনও মডেলের জন্য আপনার প্রশাসক কয়েকমাসে অকেজো হয়ে যাবে কারণ এটি যে প্রশ্নগুলি ব্যবহার করে তা ভয়াবহভাবে অদক্ষ।
সেরিন

@ সেরিন এবং অন্যান্যরা: এটি কি এখনও সত্য? আমি প্রচুর সামগ্রী সহ কোনও সাইটের জন্য জাঙ্গো-রিভার্সন ব্যবহার করতে পারি কিনা তা দেখার চেষ্টা করছি। জ্যাঙ্গো-রিভার্শনটি djangopackages.org এবং এসও পোস্টগুলিতে শীর্ষ-রেটেড বলে মনে হচ্ছে, তবে স্কেল-টু-স্কেল হওয়া আমার অ্যাপ্লিকেশনটির জন্য একটি গুরুত্বপূর্ণ অগ্রাধিকার, তাই জিজ্ঞাসা করছে
অনুপম

4
@ অনুপম, যেহেতু আমার প্রোডাকশন সাইট থেকে এটি নিষ্ক্রিয় করতে হয়েছিল তখন থেকে আমি এটি ব্যবহার করিনি। আমি সমস্যাগুলি বাগ হিসাবে চিহ্নিত করেছি, তবে দেব আমাকে উড়িয়ে দিয়ে বললেন যে এটি কোনও সমস্যা নয়, তাই আমি প্রকল্পটি পুনরায় মূল্যায়ন করি নি।
সেরিন

আমি দেখছি - দয়া করে সমস্যাটির লিঙ্কটি ভাগ করে নিতে আপত্তি করেন? আমার জাঙ্গো অ্যাপ্লিকেশনটির জন্য এটি ব্যবহার করা উচিত বা না তা গুরুত্ব সহকারে বিবেচনা করছি বলে আমার পক্ষে অত্যন্ত উপকারী হবে
অনুপম

3

উদাহরণ কোড

হ্যালো,

আমি সম্প্রতি আমাদের সার্ভারের ইনভেন্টরি ডাটাবেসের জন্য একটি "আপডেট" ভিউতে কিছু লগ ইন করেছি। আমি অনুভব করেছি যে আমি আমার "উদাহরণ" কোডটি ভাগ করব। ফাংশনটি এরপরে আমাদের "সার্ভার" অবজেক্টগুলির মধ্যে একটি, পরিবর্তিত হয়েছে এমন জিনিসের একটি তালিকা এবং কোনও সংযোজন বা পরিবর্তনগুলির একটি ক্রিয়া_ফ্ল্যাগ গ্রহণ করে। এটি জিনিসগুলিকে খুব অল্প সময়ের মধ্যে সরল করে দেয় যেখানে সংযোজনটির অর্থ "একটি নতুন সার্ভার যুক্ত হয়েছে।" আরও নমনীয় পদ্ধতির সাহায্যে কোনও সার্ভারে একটি বৈশিষ্ট্য যুক্ত করা যায়। অবশ্যই, কোনও পরিবর্তন আসলেই ঘটেছিল কিনা তা নির্ধারণ করার জন্য আমাদের বিদ্যমান ফাংশনগুলির নিরীক্ষণ করা পর্যাপ্ত পরিমাণে চ্যালেঞ্জ ছিল, তাই নতুন বৈশিষ্ট্যগুলিকে "পরিবর্তন" হিসাবে লগ করতে পেরে আমি যথেষ্ট খুশি।

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."
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.