-
Notifications
You must be signed in to change notification settings - Fork 149
Add Speaker views and API endpoints #1123
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: enext
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| from django_scopes import scopes_disabled | ||
| from rest_framework.serializers import ( | ||
| CharField, | ||
| SerializerMethodField, | ||
| URLField, | ||
| ModelSerializer, | ||
| ) | ||
|
|
||
| from eventyay.base.models.profile import SpeakerProfile | ||
|
|
||
|
|
||
| class SpeakerSerializer(ModelSerializer): | ||
| """Serializer for Speaker profiles in the API.""" | ||
|
|
||
| code = CharField(source="user.code", read_only=True) | ||
| name = CharField(source="user.name", read_only=True) | ||
| biography = CharField(read_only=True) | ||
| submissions = SerializerMethodField() | ||
|
|
||
| def get_submissions(self, obj): | ||
| """Return list of submission codes for this speaker.""" | ||
| if not obj.user: | ||
| return [] | ||
| with scopes_disabled(): | ||
| return list( | ||
| obj.user.submissions.filter(event=obj.event) | ||
| .values_list('code', flat=True) | ||
| ) | ||
|
|
||
| class Meta: | ||
| model = SpeakerProfile | ||
| fields = ('code', 'name', 'biography', 'submissions') |
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -3,6 +3,7 @@ | |||||||||
|
|
||||||||||
| # Import views directly from their modules to avoid relying on package attribute access | ||||||||||
| from .views.rooms import RoomViewSet | ||||||||||
| from .views.speaker import SpeakerViewSet | ||||||||||
| from .views.event import ( | ||||||||||
| EventView, | ||||||||||
| schedule_update, | ||||||||||
|
|
@@ -13,17 +14,18 @@ | |||||||||
| ExportView, | ||||||||||
| ) | ||||||||||
|
|
||||||||||
| orga_router = routers.DefaultRouter(trailing_slash=False) | ||||||||||
| orga_router = routers.DefaultRouter() | ||||||||||
|
|
||||||||||
| event_router = routers.DefaultRouter(trailing_slash=False) | ||||||||||
| event_router = routers.DefaultRouter() | ||||||||||
| event_router.register(r"rooms", RoomViewSet) | ||||||||||
| event_router.register(r"speakers", SpeakerViewSet, basename="speaker") | ||||||||||
|
|
||||||||||
| router = routers.DefaultRouter(trailing_slash=False) | ||||||||||
| router = routers.DefaultRouter() | ||||||||||
| urlpatterns = [ | ||||||||||
| path("events/<str:event_id>/", EventView.as_view(), name="root"), | ||||||||||
| re_path("events/(?P<event_id>[^/]+)/schedule_update/?$", schedule_update), | ||||||||||
| re_path("events/(?P<event_id>[^/]+)/delete_user/?$", delete_user), | ||||||||||
| path("events/<str:event_id>/", include(event_router.urls)), | ||||||||||
| path("events/<str:event_id>", EventView.as_view(), name="root"), | ||||||||||
|
Comment on lines
26
to
+28
|
||||||||||
| path("events/<str:event_id>/", include(event_router.urls)), | |
| path("events/<str:event_id>", EventView.as_view(), name="root"), | |
| path("events/<str:event_id>", EventView.as_view(), name="root"), | |
| path("events/<str:event_id>/", include(event_router.urls)), |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,45 @@ | ||||||
| from django.utils.functional import cached_property | ||||||
| from django_scopes import scopes_disabled | ||||||
| from rest_framework import mixins, viewsets | ||||||
| from rest_framework.pagination import PageNumberPagination | ||||||
| from rest_framework.permissions import AllowAny | ||||||
|
|
||||||
| from eventyay.base.models.profile import SpeakerProfile | ||||||
| from eventyay.api.serializers.speaker import SpeakerSerializer | ||||||
|
|
||||||
|
|
||||||
| class LargeResultsSetPagination(PageNumberPagination): | ||||||
| """Pagination class that supports a 'limit' query parameter.""" | ||||||
| page_size = 50 | ||||||
| page_size_query_param = 'limit' | ||||||
| max_page_size = 10000 | ||||||
|
||||||
| max_page_size = 10000 | |
| max_page_size = 500 |
Copilot
AI
Oct 27, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The lookup_field uses __iexact lookup which is not a valid field name but a query expression. This will cause Django to look for a field literally named 'user__code__iexact' rather than performing case-insensitive matching. Override get_object() method instead to implement case-insensitive lookup: def get_object(self): return self.get_queryset().get(user__code__iexact=self.kwargs[self.lookup_url_kwarg])
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -40,9 +40,10 @@ export function youtubeid(message) { | |||||
| return helpers.withMessage(message, helpers.regex(/^[0-9A-Za-z_-]{5,}$/)) | ||||||
| } | ||||||
| const relative = helpers.regex(/^\/.*$/) | ||||||
| const devurl = helpers.regex(/^http:\/\/localhost.*$/) // vuelidate does not allow localhost | ||||||
| // Allow localhost and local IP addresses (with or without port) | ||||||
| const localurl = helpers.regex(/^https?:\/\/(localhost|127\.0\.0\.1|0\.0\.0\.0)(:[0-9]+)?(\/.*)?$/) | ||||||
| export function url(message) { | ||||||
| return helpers.withMessage(message, (value) => (!helpers.req(value) || _url(value) || relative(value) || (ENV_DEVELOPMENT && devurl(value)))) | ||||||
| return helpers.withMessage(message, (value) => (!helpers.req(value) || _url(value) || relative(value) || localurl(value))) | ||||||
|
||||||
| return helpers.withMessage(message, (value) => (!helpers.req(value) || _url(value) || relative(value) || localurl(value))) | |
| return helpers.withMessage(message, (value) => (!helpers.req(value) || _url(value) || relative(value) || (ENV_DEVELOPMENT && localurl(value)))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment is has been mentioned in #1122 and will be resolved soon with the addition of HRM functionality in the video webapp
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This implements a try-except pattern that always attempts integer conversion first, causing an exception on every slug-based lookup. Consider checking if
event_idis numeric before attempting integer conversion:if event_id.isdigit(): request.event = Event.objects.get(id=int(event_id))followed by the slug lookup.