fairdm.contrib.contributors.admin#
Admin for contributors, affiliations, claiming and the claiming audit log.
Module Contents#
Classes#
Gate writing an Admin or Owner affiliation on |
|
Filter people by claimed or unclaimed status. |
|
Inline for a person’s email addresses. |
|
Inline for contributions. |
|
Inline for a contributor’s profile. |
|
Inline for a person’s affiliations, gated by |
|
Inline for an organisation’s members, gated by |
|
Inline for a contributor’s identifiers. |
|
Inline for an organisation’s sub-organisations. |
|
Admin for people, with import, claim links, merging and duplicate suggestions. |
|
Add a new-owner selector to the organisation changelist’s action bar. |
|
Admin for organisations, with ROR sync and ownership transfer actions. |
|
Administer affiliations directly, gated by |
|
Read-only list of claiming audit log entries, which are immutable. |
Functions#
Return a subclass of |
API#
- class AffiliationForm(*args, user=None, **kwargs)#
Bases:
django.forms.ModelFormGate writing an Admin or Owner affiliation on
manage_organization.Setting a type to ADMIN or OWNER, or changing an affiliation that already has one, is a management act, so it needs
manage_organizationon the organisation. Superusers hold that permission already. The admin and both inlines bind the acting user throughbind_affiliation_form_user, so every route that writes a type reaches this rule.Args: *args: Passed to
ModelForm. user: The user submitting the form. **kwargs: Passed toModelForm.Initialization
- clean()#
Refuse setting or changing an Admin or Owner affiliation without
manage_organization.
- bind_affiliation_form_user(form_class, user)#
Return a subclass of
form_classwithuserbound as its default.Built per request so the permission check runs against whoever submitted the form.
Args: form_class: The affiliation form class. user: The requesting user.
Returns: The bound form class.
- class ClaimedStatusFilter(request, params, model, model_admin)#
Bases:
django.contrib.admin.SimpleListFilterFilter people by claimed or unclaimed status.
Reads
is_claimedrather than the email, since an invited person has an email but has not claimed. A deactivated account no longer counts as claimed.Initialization
- title#
‘_(…)’
- parameter_name#
‘is_claimed’
- lookups(request, model_admin)#
Offer claimed and unclaimed.
- queryset(request, queryset)#
Narrow to claimed or unclaimed people.
- class AccountEmailInline(parent_model, admin_site)#
Bases:
django.contrib.admin.TabularInlineInline for a person’s email addresses.
Initialization
- model#
None
- fields#
[‘email’, ‘primary’, ‘verified’]
- extra#
0
- class ContributionInline(parent_model, admin_site)#
Bases:
django.contrib.admin.StackedInlineInline for contributions.
Initialization
- extra#
1
- fields#
(‘profile’, ‘roles’)
- class ContributorInline(parent_model, admin_site)#
Bases:
django.contrib.admin.StackedInlineInline for a contributor’s profile.
Initialization
- model#
None
- fields#
[‘profile’]
- extra#
0
- class AffiliationInline(parent_model, admin_site)#
Bases:
django.contrib.admin.StackedInlineInline for a person’s affiliations, gated by
AffiliationForm.Initialization
- model#
None
- form#
None
- fields#
[(‘organization’, ‘type’, ‘is_primary’)]
- extra#
0
- get_formset(request, obj=None, **kwargs)#
Bind the requesting user into
AffiliationForm.
- class MemberInline(parent_model, admin_site)#
Bases:
django.contrib.admin.StackedInlineInline for an organisation’s members, gated by
AffiliationForm.Initialization
- model#
None
- form#
None
- fk_name#
‘organization’
- fields#
[(‘person’, ‘type’, ‘is_primary’)]
- extra#
0
- verbose_name#
‘Member’
- verbose_name_plural#
‘Members’
- get_formset(request, obj=None, **kwargs)#
Bind the requesting user into
AffiliationForm.
- class IdentifierInline(parent_model, admin_site)#
Bases:
django.contrib.admin.StackedInlineInline for a contributor’s identifiers.
Initialization
- model#
None
- fields#
[‘type’, ‘value’]
- extra#
0
- class SubOrganizationInline(parent_model, admin_site)#
Bases:
django.contrib.admin.TabularInlineInline for an organisation’s sub-organisations.
Initialization
- model#
None
- fk_name#
‘parent’
- fields#
[‘name’]
- extra#
0
- verbose_name#
‘_(…)’
- verbose_name_plural#
‘_(…)’
- class UserAdmin(model, admin_site)#
Bases:
django.contrib.auth.admin.UserAdmin,hijack.contrib.admin.HijackUserAdminMixin,import_export.admin.ImportExportModelAdminAdmin for people, with import, claim links, merging and duplicate suggestions.
Initialization
- base_model#
None
- show_in_index#
True
- change_form_template#
‘contributors/admin/change_form.html’
- resource_classes#
None
- skip_import_confirm#
True
- inlines#
None
- list_display#
[‘first_name’, ‘last_name’, ‘email’, ‘is_staff’, ‘account_state’]
- list_filter#
()
- exclude#
(‘username’,)
- autocomplete_fields#
[‘groups’]
- readonly_fields#
[‘synced_data’, ‘last_synced’, ‘uuid’, ‘added’, ‘modified’]
- fieldsets#
((‘Basic info’,), (), (‘Permissions’,))
- add_fieldsets#
((None,),)
- search_fields#
(‘email’, ‘name’, ‘uuid’)
- ordering#
(‘last_name’,)
- actions#
[‘generate_claim_link_action’, ‘merge_person_action’]
- get_fieldsets(request, obj=None)#
Drop the account-escalation fields for a non-superuser.
groupsis dropped too unless the user holdsauth.view_group, as a group membership grants a role’s rights.
- get_form(request, obj=None, **kwargs)#
Drop
passwordfrom the built form for a non-superuser.
- get_actions(request)#
Drop the merge and claim-link actions for users the views would refuse.
- account_state(obj)#
Show the person’s derived account state.
- merge_person_action(request, queryset)#
Redirect to the merge page for the one selected person.
- generate_claim_link_action(request, queryset)#
Redirect to the claim-link page for the one selected person.
- change_view(request, object_id, form_url='', extra_context=None)#
Add possible duplicates, minus those dismissed this session, to the change form.
- dismiss_candidate_view(request, pk, candidate_pk)#
Dismiss a duplicate candidate for this session and return to the change page.
Args: request: The current request. pk: The person being edited. candidate_pk: The candidate to dismiss.
Returns: A redirect to the person’s change page.
- get_urls()#
Add the claim-link, merge and dismiss-candidate routes.
- claim_link_view(request, pk)#
Render the claim link page for a person.
A claim token is a credential, so the permission check comes first.
Args: request: The current request. pk: The person’s primary key.
Returns: The rendered page.
Raises: PermissionDenied: The user may not manage people.
- merge_view(request, pk)#
Render the merge page for a person and merge them into the chosen person on POST.
Merging deletes the discarded person and moves their affiliations, permissions, emails and social account, so the permission check comes first.
Args: request: The current request. pk: The primary key of the person to discard.
Returns: The rendered page, or a redirect to the surviving person after a merge.
Raises: PermissionDenied: The user may not manage people.
- class OrganizationActionForm(data=None, files=None, auto_id='id_%s', prefix=None, initial=None, error_class=ErrorList, label_suffix=None, empty_permitted=False, field_order=None, use_required_attribute=None, renderer=None, bound_field_class=None)#
Bases:
django.contrib.admin.helpers.ActionFormAdd a new-owner selector to the organisation changelist’s action bar.
The transfer action reads the value from
request.POSTwithout validating this form.Attributes: new_owner: The person to become owner.
Initialization
- new_owner#
‘PersonChoiceField(…)’
- class OrganizationAdmin(model, admin_site)#
Bases:
django.contrib.admin.ModelAdminAdmin for organisations, with ROR sync and ownership transfer actions.
Initialization
- base_model#
None
- show_in_index#
True
- inlines#
None
- action_form#
None
- list_display#
[‘name’, ‘city’, ‘country’, ‘lat’, ‘lon’]
- list_filter#
[‘country’]
- search_fields#
[‘name’]
- readonly_fields#
[‘synced_data’, ‘last_synced’, ‘uuid’, ‘added’, ‘modified’]
- fieldsets#
((None,), (), ())
- actions#
[‘sync_from_ror’, ‘transfer_ownership_action’]
- get_readonly_fields(request, obj: fairdm.contrib.contributors.models.Organization | None = None)#
Make the synced fields read-only once the organisation has synced data.
- sync_from_ror(request, queryset)#
Queue a ROR sync for each selected organisation that has a ROR identifier.
- transfer_ownership_action(request, queryset)#
Transfer the selected organisation to the member chosen in the action bar.
- class AffiliationAdmin(model, admin_site)#
Bases:
django.contrib.admin.ModelAdminAdminister affiliations directly, gated by
manage_organizationon each organisation.Initialization
- form#
None
- list_display#
[‘person’, ‘organization’, ‘type’, ‘is_primary’]
- list_filter#
[‘type’, ‘is_primary’]
- autocomplete_fields#
[‘person’, ‘organization’]
- get_form(request, obj=None, **kwargs)#
Bind the requesting user into
AffiliationForm.
- get_queryset(request)#
Limit a non-superuser to affiliations of organisations they own.
- has_change_permission(request, obj=None)#
Refuse changing an affiliation without
manage_organizationon its organisation.
- has_delete_permission(request, obj=None)#
Refuse deleting an affiliation without
manage_organizationon its organisation.
- class ClaimingAuditLogAdmin(model, admin_site)#
Bases:
django.contrib.admin.ModelAdminRead-only list of claiming audit log entries, which are immutable.
Initialization
- list_display#
[‘timestamp’, ‘method’, ‘source_person’, ‘target_person’, ‘initiated_by’, ‘success’]
- list_filter#
[‘method’, ‘success’]
- search_fields#
[‘source_person__name’, ‘target_person__name’, ‘initiated_by__name’]
- date_hierarchy#
‘timestamp’
- ordering#
[‘-timestamp’]
- has_add_permission(request)#
Never allow adding an entry.
- has_view_permission(request, obj=None)#
Allow the list but not an entry’s detail page.
- has_change_permission(request, obj=None)#
Never allow changing an entry.
- has_delete_permission(request, obj=None)#
Never allow deleting an entry.