diff --git a/backend/Dockerfile b/backend/Dockerfile index 09e37f91..93033e8b 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -34,4 +34,4 @@ RUN chmod +x startup.sh EXPOSE 8000 # Run startup script -CMD ["./startup.sh", "gunicorn", "--bind", "0.0.0.0:8000", "--timeout", "180", "--workers", "2", "tally.wsgi:application"] +CMD ["./startup.sh", "gunicorn", "--bind", "0.0.0.0:8000", "--timeout", "180", "--workers", "2", "--access-logfile", "-", "--error-logfile", "-", "--capture-output", "--log-level", "info", "tally.wsgi:application"] diff --git a/backend/deploy-apprunner-dev.sh b/backend/deploy-apprunner-dev.sh index 5c9f0a2e..6f27d85d 100755 --- a/backend/deploy-apprunner-dev.sh +++ b/backend/deploy-apprunner-dev.sh @@ -95,7 +95,7 @@ if aws apprunner describe-service --service-arn arn:aws:apprunner:$REGION:$ACCOU "TWITTER_REDIRECT_URI": "$SSM_PREFIX/$SSM_ENV/twitter_redirect_uri", "DISCORD_REDIRECT_URI": "$SSM_PREFIX/$SSM_ENV/discord_redirect_uri" }, - "StartCommand": "./startup.sh gunicorn --bind 0.0.0.0:8000 --timeout 180 --workers 2 tally.wsgi:application" + "StartCommand": "./startup.sh gunicorn --bind 0.0.0.0:8000 --timeout 180 --workers 2 --access-logfile - --error-logfile - --capture-output --log-level info tally.wsgi:application" }, "ImageRepositoryType": "ECR" }, @@ -271,7 +271,7 @@ EOF "TWITTER_REDIRECT_URI": "$SSM_PREFIX/$SSM_ENV/twitter_redirect_uri", "DISCORD_REDIRECT_URI": "$SSM_PREFIX/$SSM_ENV/discord_redirect_uri" }, - "StartCommand": "./startup.sh gunicorn --bind 0.0.0.0:8000 --timeout 180 --workers 2 tally.wsgi:application" + "StartCommand": "./startup.sh gunicorn --bind 0.0.0.0:8000 --timeout 180 --workers 2 --access-logfile - --error-logfile - --capture-output --log-level info tally.wsgi:application" }, "ImageRepositoryType": "ECR" }, diff --git a/backend/deploy-apprunner.sh b/backend/deploy-apprunner.sh index 111353cf..d05e3b37 100755 --- a/backend/deploy-apprunner.sh +++ b/backend/deploy-apprunner.sh @@ -234,7 +234,7 @@ if aws apprunner describe-service --service-arn arn:aws:apprunner:$REGION:$ACCOU "DISCORD_ROLE_SUBMISSION_SYNC_GRACE_SECONDS": "$SSM_PREFIX/prod/discord_role_submission_sync_grace_seconds", "DISCORD_REDIRECT_URI": "$SSM_PREFIX/prod/discord_redirect_uri" }, - "StartCommand": "./startup.sh gunicorn --bind 0.0.0.0:8000 --timeout 180 --workers 2 tally.wsgi:application" + "StartCommand": "./startup.sh gunicorn --bind 0.0.0.0:8000 --timeout 180 --workers 2 --access-logfile - --error-logfile - --capture-output --log-level info tally.wsgi:application" }, "ImageRepositoryType": "ECR" }, @@ -335,7 +335,7 @@ else "DISCORD_ROLE_SUBMISSION_SYNC_GRACE_SECONDS": "$SSM_PREFIX/prod/discord_role_submission_sync_grace_seconds", "DISCORD_REDIRECT_URI": "$SSM_PREFIX/prod/discord_redirect_uri" }, - "StartCommand": "./startup.sh gunicorn --bind 0.0.0.0:8000 --timeout 180 --workers 2 tally.wsgi:application" + "StartCommand": "./startup.sh gunicorn --bind 0.0.0.0:8000 --timeout 180 --workers 2 --access-logfile - --error-logfile - --capture-output --log-level info tally.wsgi:application" }, "ImageRepositoryType": "ECR" }, diff --git a/backend/projects/admin.py b/backend/projects/admin.py index 4f509c9d..babe38a7 100644 --- a/backend/projects/admin.py +++ b/backend/projects/admin.py @@ -1,4 +1,6 @@ from django.contrib import admin +from django.urls import reverse +from django.utils.html import format_html, format_html_join from utils.admin_mixins import CloudinaryUploadMixin @@ -31,7 +33,7 @@ class ProjectAdmin(CloudinaryUploadMixin, admin.ModelAdmin): search_fields = ('title', 'slug', 'description', 'details', 'user__name', 'user__address') list_editable = ('order', 'status') raw_id_fields = ('user',) - filter_horizontal = ('participants', 'related_contributions') + autocomplete_fields = ('participants', 'related_contributions') prepopulated_fields = {'slug': ('title',)} readonly_fields = ( 'created_at', @@ -40,6 +42,8 @@ class ProjectAdmin(CloudinaryUploadMixin, admin.ModelAdmin): 'hero_image_tablet_public_id', 'hero_image_mobile_public_id', 'user_profile_image_public_id', + 'selected_participants', + 'selected_related_contributions', ) ordering = ('order', '-created_at') @@ -48,7 +52,13 @@ class ProjectAdmin(CloudinaryUploadMixin, admin.ModelAdmin): 'fields': ('title', 'slug', 'author', 'description', 'status', 'order'), }), ('Relations', { - 'fields': ('user', 'participants', 'related_contributions'), + 'fields': ( + 'user', + 'participants', + 'selected_participants', + 'related_contributions', + 'selected_related_contributions', + ), }), ('Project Detail', { 'fields': ( @@ -75,3 +85,57 @@ class ProjectAdmin(CloudinaryUploadMixin, admin.ModelAdmin): 'classes': ('collapse',), }), ) + + @admin.display(description='Selected participants') + def selected_participants(self, obj): + if not obj or not obj.pk: + return 'Save the project before reviewing selected participants.' + + participants = obj.participants.order_by('name', 'email', 'id') + if not participants.exists(): + return 'No participants selected.' + + rows = ( + ( + reverse('admin:users_user_change', args=[participant.pk]), + participant.name or participant.email or participant.address or f'User {participant.pk}', + participant.email or participant.address or '', + ) + for participant in participants + ) + return format_html( + '