سؤال

لقد بدأت مؤخرا في استخدام Django لإدارة تطبيق موجود كبير تم زرعه عضويا على مر السنين باستخدام الملتوية. بدأت في تجربة Django وواجهة الإدارة التلقائية وأنت سعيد للغاية بالنتائج.

شيء واحد يبدو أنه مفقود لأغراضي هو القدرة على منح المستخدمين قراءة فقط الوصول إلى البيانات. على سبيل المثال، لدينا دور حيث يسمح للناس بتسجيل الدخول وإنشاء أوامر الشراء. كما أنها بحاجة إلى أن تكون قادرة على عرض، ولكن لا تحرير بيانات العميل أو المنتج الأخرى.

كيف يمكنني إنشاء أذونات "عرض" في مسؤول Django بحيث يمكن للمستخدمين تعديل البيانات لبعض الجداول، مع قراءة الوصول فقط إلى الآخرين؟

تحديث: يظهر مسؤول django أن تعطيني مخيرة واجهة CRUD. كيف يمكنني الحصول على الجزء الأول فقط مع الأذونات والمجموعات المرتبطة؟

تحديث 2010-FE-12: سيتضمن الآن DJango 1.2 للقراءة فقط. التفاصيل أدناه.


أجبت على سؤالي الخاص أعتقد. نقل المحتوى إلى إجابة حقيقية أدناه.

هل كانت مفيدة؟

المحلول 5

يتم الآن تضمين القدرة على إضافة حقول للقراءة فقط إلى عرض المسؤول في إصدار Django الإصدار 1.2.

انظر تذكرة رقم 342http://code.djangoproject.com/ticket/342.

انظر التغييرات رقم 11965http://code.djangoproject.com/changeset/11965.

انظر الوثائقhttp://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.modeladmin.Readonly_field.

نصائح أخرى

هذه هي الطريقة التي غيرت django 1.0.2 لإضافة أذونات "عرض". آسف لا يوجد فرق متاح.

x] 1. أضف "عرض" إلى قائمة الأذونات الافتراضية

#./contrib/auth/management/__init__.py
def _get_all_permissions(opts):
    "Returns (codename, name) for all permissions in the given opts."
    perms = []
    for action in ('add', 'change', 'delete', 'view'):
        perms.append((_get_permission_codename(action, opts), u'Can %s %s' % (action, opts.verbose_name_raw)))
    return perms + list(opts.permissions)

x] 2. اختبار إذن "عرض" يضاف إلى جميع النماذج

run manage.py syncdb

أكدت أنه تمت إضافة إذن الرأي الآن لجميع الجداول في جدول Auth_Permissions

x] 3. أضف "get_view_permission" إلى فئة النموذج الافتراضية.

إضافة get_view_permission إلى فئة النموذج. يمكنك العثور على هذا في الملف ./db/models/Ooptions.py يستخدم هذا من قبل فئة المسؤول في الخطوة التالية.

def get_view_permission(self):
    return 'view_%s' % self.object_name.lower()

x] 4. إضافة "has_view_permission" إلى فئة المسؤول الافتراضية

فقط لتكون متسقة، سأضيف "has_view_permission" إلى النظام. يبدو أنه ينبغي أن يكون في مكان ما في contrib / admin / options.py. وبعد بالتأكيد ما إذا كان المستخدم لديه تغيير إذن، ثم عرض الأذونات ضمنا تلقائيا.

# /contrib/admin/options.py
# Added has_view_permissions
def has_view_permission(self, request, obj=None):
    """
    Returns True if the given request has permission to change or view
    the given Django model instance.

    If `obj` is None, this should return True if the given request has
    permission to change *any* object of the given type.
    """
    opts = self.opts
    return self.has_change_permission(request, obj) or \
        request.user.has_perm(opts.app_label + '.' + opts.get_view_permission())

# modified get_model_perms to include 'view' too.
# No idea where this may be used, but trying to stay consistent
def get_model_perms(self, request):
        """
        Returns a dict of all perms for this model. This dict has the keys
        ``add``, ``change``, and ``delete`` and ``view`` mapping to the True/False
        for each of those actions.
        """
        return {
            'add': self.has_add_permission(request),
            'change': self.has_change_permission(request),
            'delete': self.has_delete_permission(request),
            'view': self.has_view_permission(request),
        }

# modified response_add function to return the user to the mode list
# if they added a unit and have view rights
... 
    else:
        self.message_user(request, msg)

        # Figure out where to redirect. If the user has change permission,
        # redirect to the change-list page for this object. Otherwise,
        # redirect to the admin index.
        #if self.has_change_permission(request, None):
        if self.has_change_permission(request, None) or self.has_view_permission(request, None):
            post_url = '../'
        else:
            post_url = '../../../'
        return HttpResponseRedirect(post_url)

 # modified the change_view function so it becomes the details 
 # for users with view permission

    #if not self.has_change_permission(request, obj):
    if not (self.has_change_permission(request, obj) or (self.has_view_permission(request, obj) and not request.POST)):
        raise PermissionDenied


  # modified the changelist_view function so it shows the list of items
  # if you have view permissions
def changelist_view(self, request, extra_context=None):
    "The 'change list' admin view for this model."
    from django.contrib.admin.views.main import ChangeList, ERROR_FLAG
    opts = self.model._meta
    app_label = opts.app_label
    #if not self.has_change_permission(request, None):
    if not (self.has_change_permission(request, None) or self.has_view_permission(request, None)):
        raise PermissionDenied

X] 5. تحديث القالب الافتراضي إلى قائمة النماذج إذا كان لدى المستخدم إذن

قمت بتعديل القالب الافتراضي في Contrib / Admin / Templates / Admin / Index.html. يمكن أيضا معالجة هذا عن طريق نسخ الملف إلى دليل القوالب المحلية بدلا من ذلك. لقد قمت بتغييرات في كلاهما، ولدي نسخة إذا قمت بالترقية الأحدث الكتابة فوق التغييرات الخاصة بي.

 {% for model in app.models %}
            <tr>
            {% if model.perms.change %}
                <th scope="row"><a href="{{ model.admin_url }}">{{ model.name }}</a></th>
            {% else %}
                {% if model.perms.view %}
                    <th scope="row"><a href="{{ model.admin_url }}">{{ model.name }}</a></th>
                {% else %}
                    <th scope="row">{{ model.name }}</th>
                {% endif %}
            {% endif %}

x] 6. تأكيد المستخدم يمكن "عرض" ولكن ليس "تغيير" النموذج

وجدت Contrib / admin / templatetags / admin_modify.py يبدو للتحكم في حفظ / حفظ ومتابعة الأزرار التي تظهر أم لا. تم تغيير حقل "حفظ" من الافتراضي الصحيح دائما، للتحقق من وجود السياق والأذونات. يجب أن يكون المستخدم قادرا على حفظ إذا كان لديهم تغيير أو إضافة أذونات.

 'show_save': (change and context['has_change_permission']) or (context['add'] and context['has_add_permission'])

x] 7. قم بإزالة زر "حفظ وإضافة" آخر "إذا كان المستخدم يشاهد عنصر

تعديل المساهمة / المشرف / templatetags / admin_modify.py مرة أخرى. لا أعرف معنى "Save_as"، لذلك ربما كسرت شيئا، ولكن يبدو أن العمل.

    #'show_save_and_add_another': context['has_add_permission'] and
    #                    not is_popup and (not save_as or context['add']) ,
    'show_save_and_add_another': not is_popup and
        (( change and context['has_change_permission']) or (context['add'] and context['has_add_permission']))
        and
        (not save_as or context['add']),

x] 8. تعديل إذن "عرض" لجعل النموذج للقراءة فقط

إذا كان لدى المستخدم إذن "عرض" وإذن "تغيير"، فلا تفعل شيئا. تغيير طريقة العرض عرض.

إذا كان لدى المستخدم إذن "عرض" دون تغيير "تغيير"، ثم قم بتغيير النماذج الافتراضية وإضافة تعطيل أو سمات Readonly إلى عناصر النموذج. لا يدعم جميع المتصفحات هذا، ولكن لأغراضي، يمكنني أن أطلب استخدام المستخدمين من اليمين. مثال المعوقين / القراءة

وجدت أن جميع المتصفحات تكرم "Readonly"، لذلك فإنها تحدد بعض الضوابط إلى Readonly، والبعض الآخر للمعوقين. يتيح ذلك للمستخدمين نسخ البيانات من عناصر تحكم النص إذا لزم الأمر.

#/django/contrib/admin/templates/admin/change_form.html

{# JavaScript for prepopulated fields #}
{% prepopulated_fields_js %}

</div>
</form></div>
{% if has_view_permission and not has_change_permission %}
    <script type="text/javascript">
    jQuery('input:text').attr('readonly', 'readonly');
    jQuery('textarea').attr('readonly', 'readonly');
    jQuery('input:checkbox').attr('disabled', true);
    jQuery('select').attr('disabled', true);
    jQuery('.add-another').hide();
    </script>
{% endif %}

هذا المقتطف سيجعل المشرق واحد فقط مع وصول الكتابة.

class AdminOwn(admin.ModelAdmin):
    def get_readonly_fields(self, request, obj=None):
        if request.user.is_superuser:
            return self.readonly_fields
        #get all fields as readonly
        fields = [f.name for f in self.model._meta.fields]
        return fields

هناك حق في المشرف. يمكنك تعيين أذونات للمستخدمين والمجموعات في المسؤول لإضافة وتغيير وحذف طرز محددة.

تحديث: عذرا، أسيء فهم السؤال لأنني أسيء تفسير طريقة عرض كلمة لمنحها معنى Django بدلا من "القراءة فقط". إذا كنت تريد القراءة فقط باستخدام المشرف، أعتقد أنك ستحتاج إلى القيام ببعض العمل. يرى هذا الموضوع, ، حيث يقول جيمس بينيت مدير إصدار Django):

كما ستجد عن طريق البحث عن أرشيف هذه القائمة، فهذا ليس شيئا تم تصميم واجهة إدارة DJango لدعمه، ولذا سيحتاج أي حل إلى القدوم بالكامل منك لكتابة الرمز الخاص بك.

و

يعمل مسؤول Django على ثلاثة أذونات: "إضافة"، "تغيير" و "حذف". لا يوجد "عرض ولكن لا تقدم أي تعديلات"، وبالتالي لا توجد طريقة لتطبيق مثل هذا القيد دون القيام بترميز مخصص كبير.

سيتضمن العمل الإضافي إضافتك بإذن "Readonly" بإذن من طرازات معينة، وتغيير قوالب المسؤول الأساسية للتحقق مما إذا كان لدى المستخدم هذا الإذن - وإذا كان الأمر كذلك، فقم بتعطيل بعض الضوابط (مثل حفظ الأزرار) وجعل الآخرين للقراءة فقط وبعد من شأنها أن تمنع العبث غير الرسمي، ولكن قد تحتاج أيضا إلى تعديل منطق جانب الخادم للتحقق من نفس الإذن، لتجنب أي المشاركات التي تم إجراؤها بطريقة متستر للتحايل على الأذونات.

يمكنك إنشاء إذن "Readonly" في النموذج الخاص بك واستخدام رمز Jasuca مع تعديل:

models.py:

class MyModel(models.Model):
    name = models.CharField(max_length=100)
    description = models.CharField(max_length=256, null=True, blank=True)

    class Meta:
        permissions = (
            ('readonly_mymodel','Readonly MyModel'),
        )

admin.py:

class MyModelAdmin(admin.ModelAdmin):
    def get_readonly_fields(self, request, obj=None):
        if not request.user.is_superuser and request.user.has_perm('mymodel.readonly_mymodel'):
            return [f.name for f in self.model._meta.fields]
        return self.readonly_fields

في مسؤول APLICATION، يجب عليك إعطاء إذن من "التغيير" و "Readonly" للمستخدم.

يمكنك إنشاء مجموعات في وحدة المصادقة. ثم في Admin.py بناء على تسجيل الدخول إلى مجموعة المستخدمين، قم بتعيين سمة Readonly_fields الخاصة ب Smocradmin. أضف طريقة Def Has_add_permission (الذات، طلب) لإرجاع False للمجموعة بإذن Readonly. إعطاء إضافة، تعديل الأذونات للمجموعة. سيكونون قادرين على قراءة السمات النموذجية فقط.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top