from django.contrib import admin from django.utils.html import format_html from research.models import ResearchStudy, ResearchStudyArm, ResearchParticipant @admin.register(ResearchStudy) class ResearchStudyAdmin(admin.ModelAdmin): list_display = ['id', 'name', 'active', 'generation_mode', 'randomisation_mode', 'created_at'] list_filter = ['active', 'generation_mode', 'randomisation_mode', 'created_at'] search_fields = ['name', 'description'] readonly_fields = ['created_at', 'updated_at'] fieldsets = ( ('Study Information', { 'fields': ('name', 'description', 'active') }), ('Participant Creation', { 'fields': ('generation_mode', 'collect_demographics'), 'description': 'Configure how participants are created and what data is collected.' }), ('Randomisation Strategy', { 'fields': ('randomisation_mode', 'balance_within_candidate_group', 'allocation_targets'), 'description': 'Configure how participants are assigned to arms.' }), ('Authors', { 'fields': ('author',), }), ('Timestamps', { 'fields': ('created_at', 'updated_at'), 'classes': ('collapse',) }), ) @admin.register(ResearchStudyArm) class ResearchStudyArmAdmin(admin.ModelAdmin): list_display = ['name', 'study', 'packet', 'active', 'sort_order', 'order_sequence'] list_filter = ['study', 'active', 'order_sequence'] search_fields = ['name', 'study__name', 'packet__name'] fieldsets = ( ('Arm Information', { 'fields': ('study', 'name', 'packet', 'active', 'sort_order') }), ('Randomisation', { 'fields': ('allocation_weight',), 'description': 'Used for completely-random allocation.' }), ('Ordering & Prerequisites', { 'fields': ('order_sequence', 'required_previous_arm'), 'description': 'Configure sequential completion requirements.' }), ) def get_form(self, request, obj=None, **kwargs): """Pre-filter related fields based on study.""" form = super().get_form(request, obj, **kwargs) if obj and hasattr(obj, 'study'): form.base_fields['required_previous_arm'].queryset = ResearchStudyArm.objects.filter( study=obj.study ).exclude(pk=obj.pk) return form @admin.register(ResearchParticipant) class ResearchParticipantAdmin(admin.ModelAdmin): list_display = ['pseudo_id', 'study', 'assigned_arm', 'cid_user_display', 'consented', 'assigned_at'] list_filter = ['study', 'assigned_arm', 'consented', 'created_at'] search_fields = ['pseudo_id', 'study__name', 'cid_user__cid', 'email'] readonly_fields = ['created_at', 'updated_at', 'cid_user_info'] fieldsets = ( ('Study & ID', { 'fields': ('study', 'pseudo_id') }), ('CID User', { 'fields': ('cid_user', 'cid_user_info'), 'description': 'Associated CID user for study access.' }), ('Demographics', { 'fields': ('candidate_group', 'age_band', 'sex', 'training_grade', 'years_experience', 'email'), }), ('Assignment', { 'fields': ('assigned_arm', 'assignment_method', 'assigned_at'), }), ('Consent & Status', { 'fields': ('consented', 'completed_arms'), }), ('User Link', { 'fields': ('user_user',), 'classes': ('collapse',) }), ('Timestamps', { 'fields': ('created_at', 'updated_at'), 'classes': ('collapse',) }), ) def cid_user_display(self, obj): """Display CID number with link.""" if obj.cid_user: return format_html( '{}', obj.cid_user.cid ) return '-' cid_user_display.short_description = 'CID' def cid_user_info(self, obj): """Display full CID user info.""" if obj.cid_user: return format_html( 'CID: {}
Passcode: {}
Name: {}', obj.cid_user.cid, obj.cid_user.passcode, obj.cid_user.name ) return 'Not yet assigned' cid_user_info.short_description = 'CID User Information'