Задать вопрос

Тел: +7 965 3737 888

458

Просмотров

1

Ответов

FieldAccessForm (per-field user access for forms derived from models)

<p>=== version 2 ===</p>
<blockquote>
<p>Parts of this code are based off of source from <em>davidcramer</em> on #django and I'd like to thank him for his assistance.</p>
</blockquote>
<p>Example:</p>
# forms.py
...
class ForumPostForm(FieldAccessForm):
    class Meta:
        model = ForumPost
    class FieldAccess:
        moderator = FieldAccessLevel(
            lambda user, instance: user.get_profile().is_moderator,
            enable = ('approve', 'delete', 'edit')
        member = FieldAccessLevel(
            lambda user, instance: user.is_active,
            enable = ('edit',),
            exclude = ('approve', 'delete')
...

# template
...
&lt;form action="" method="POST"&gt;
    &lt;table&gt;
        {% for field in form %}
            &lt;tr&gt;&lt;th&gt;{{ field.label_tag }}&lt;/th&gt;&lt;td&gt;
                {% if not field.field.disabled %}
                    {{ field }}
                {% else %}
                    {{ field.field.value }}
                {% endif %}
            &lt;/td&gt;&lt;/tr&gt;
        {% endfor %}
    &lt;/table&gt;
    &lt;p&gt;&lt;input type="submit" value="Update" /&gt;&lt;/p&gt;
&lt;/form&gt;
...

<p>This class will grant or deny access to individual fields according to simple rules. The first argument must be a user object, but otherwise, this class is instantiated the same as a ModelForm.</p>
<p>To utilize this code, inherit your form from FieldAccessForm, and create an inner class on your form called FieldAccess. Variables added to this inner class must have the same structure as that provided by the FieldAccessLevel class, which defines an access level, and the fields which apply to that access level.</p>
<p>FieldAccessLevel takes as it's first argument a callable rule that validates this access level. That rule will be called with two arguments: 'user' (current user requesting access) and 'instance' (model instance in question).</p>
<p>The keyword arguments to FieldAccessLevel are field groups which are used to determine which fields on this form are to be enabled and/or excluded, when the current user matches this access level. The term exclude indicates fields which are not to be rendered in the form at all.</p>
<p>Any fields not grouped in either 'enable' or 'exclude' will be disabled by default.</p>
<p>Superusers are always assumed to have full access. Otherwise, if a field is not specified with the FieldAccess inner class, then it is disabled by default. In other words, all users (except superusers) are denied access to all fields, unless they are 
specifically given access on a per-field basis.</p>
<p>It is worth mentioning that multiple access levels can apply simultaneously, giving a user access to fields from all levels for which he matches the rule.</p>
<p>If a user is denied access to a field, then the widget for that field is flagged as disabled and readonly. The field is also given two new attributes: a boolean 'disabled', and a 'value' containing the instanced model field. These two attributes allow a template author to have great control over the display of the form. For 
example, she may render the plain text value of a field instead of the disabled widget.</p>
<p>The FieldAccess inner class also allows one to conditionally exclude fields from being rendered by the form. These exclusions operate very similarly to the standard Meta exclude option, except that they apply only to the access level in question.</p>
<p>Note: The FieldAccess inner class may be used on both the form and the model; however, generally it makes more sense on the form. If you do use FieldAccess on both the form and model, be aware that both definitions will apply simultaneously. All access levels for which the user passes the rule will be processed, regardless of whether they were found on the form or the model.</p>

Вопрос полезен? Да0/Нет0
file_5174.py(2.3Кб)
None

Ответы (1):

Ответkillarny:24.10.2008
Ответ полезен? Да0/Нет0

I've updated this to the newest code that I'm using, where I made a few improvements to the syntax of the FieldAccess inner class.