Skip to content

Commit 3ed029c

Browse files
authored
Migrate schedule types to Strawberry Django (#4728)
1 parent 9547241 commit 3ed029c

10 files changed

Lines changed: 461 additions & 199 deletions

File tree

backend/api/conferences/schema.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
from api.context import Info
21
from api.conferences.types import Conference
32
import strawberry
3+
import strawberry_django
44

5-
from conferences.models import Conference as ConferenceModel
5+
from conferences import models
66

77

88
@strawberry.type
99
class ConferenceQuery:
10-
@strawberry.field
11-
def conference(self, info: Info, code: str) -> Conference:
12-
return ConferenceModel.objects.prefetch_related("durations").get(code=code)
10+
@strawberry_django.field
11+
def conference(self, code: str) -> Conference:
12+
return models.Conference.objects.filter(code=code)

backend/api/conferences/tests/test_query_talk.py

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -144,23 +144,29 @@ def test_abstract_shows_keynote_description(graphql_client, user):
144144
}
145145

146146

147-
def test_fetch_schedule_talk(simple_schedule_item, graphql_client, user):
147+
def test_fetch_schedule_talk(
148+
simple_schedule_item, graphql_client, user, django_assert_num_queries
149+
):
148150
graphql_client.force_login(user)
149151

150152
schedule_item = simple_schedule_item
151-
response = graphql_client.query(
152-
"""query($slug: String!, $code: String!) {
153-
conference(code: $code) {
154-
talk(slug: $slug) {
155-
youtubeVideoId
156-
userHasSpot
157-
hasSpacesLeft
158-
spacesLeft
153+
with django_assert_num_queries(4):
154+
response = graphql_client.query(
155+
"""query($slug: String!, $code: String!) {
156+
conference(code: $code) {
157+
talk(slug: $slug) {
158+
youtubeVideoId
159+
userHasSpot
160+
hasSpacesLeft
161+
spacesLeft
162+
}
159163
}
160-
}
161-
}""",
162-
variables={"slug": schedule_item.slug, "code": schedule_item.conference.code},
163-
)
164+
}""",
165+
variables={
166+
"slug": schedule_item.slug,
167+
"code": schedule_item.conference.code,
168+
},
169+
)
164170

165171
assert response["data"]["conference"]["talk"] == {
166172
"youtubeVideoId": "AbCdEfGhIjK",

backend/api/conferences/types.py

Lines changed: 19 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
from api.context import Info
2-
from django.db.models import Case, When, Value, IntegerField
3-
from django.db.models import Prefetch
42
from participants.models import Participant as ParticipantModel
53
from datetime import datetime
64
from api.participants.types import Participant
@@ -139,27 +137,31 @@ def youtube_video_id(self) -> str | None:
139137
return schedule_item.youtube_video_id if schedule_item else None
140138

141139

142-
@strawberry.type
140+
@strawberry_django.type(conference_models.Conference)
143141
class Conference:
144-
id: strawberry.ID
142+
id: strawberry.auto
145143

146-
name: str = strawberry.field(resolver=make_localized_resolver("name"))
147-
introduction: str = strawberry.field(
148-
resolver=make_localized_resolver("introduction")
144+
name: str = strawberry_django.field(
145+
resolver=make_localized_resolver("name"), only=["name"]
146+
)
147+
introduction: str = strawberry_django.field(
148+
resolver=make_localized_resolver("introduction"), only=["introduction"]
149149
)
150-
code: str
151-
hostname: str
150+
code: strawberry.auto
151+
hostname: strawberry.auto
152152
start: datetime
153153
end: datetime
154154
map: Map | None = strawberry.field(resolver=resolve_map)
155155

156-
pretix_event_url: str
156+
pretix_event_url: strawberry.auto
157157

158-
@strawberry.field
158+
@strawberry_django.field(
159+
only=["pretix_organizer_id", "pretix_event_id"],
160+
)
159161
def voucher(self, info: Info, code: str) -> Voucher | None:
160162
return get_voucher(self, code)
161163

162-
@strawberry.field
164+
@strawberry_django.field(only=["timezone"])
163165
def timezone(self, info: Info) -> str:
164166
return str(self.timezone)
165167

@@ -207,9 +209,7 @@ def topics(self, info: Info) -> list[Topic]:
207209
def languages(self, info: Info) -> list[Language]:
208210
return self.languages.all()
209211

210-
@strawberry.field
211-
def durations(self, info: Info) -> list["Duration"]:
212-
return self.durations.all()
212+
durations: list["Duration"]
213213

214214
@strawberry.field
215215
def submission_types(self, info: Info) -> list[SubmissionType]:
@@ -272,9 +272,9 @@ def talks(self, info: Info) -> list[ScheduleItem]:
272272
.all()
273273
)
274274

275-
@strawberry.field
275+
@strawberry_django.field
276276
def talk(self, info: Info, slug: str) -> ScheduleItem | None:
277-
return self.schedule_items.filter(slug=slug).prefetch_related("rooms").first()
277+
return self.schedule_items.filter(slug=slug)
278278

279279
@strawberry.field
280280
def ranking(self, info: Info, topic: strawberry.ID) -> RankRequest | None:
@@ -296,74 +296,9 @@ def ranking(self, info: Info, topic: strawberry.ID) -> RankRequest | None:
296296
stats=rank_request.stats.all(),
297297
)
298298

299-
@strawberry.field
299+
@strawberry_django.field
300300
def days(self, info: Info) -> list[Day]:
301-
days = list(
302-
self.days.order_by("day")
303-
.prefetch_related(
304-
"slots",
305-
"slots__day",
306-
"slots__day__added_rooms",
307-
"slots__day__added_rooms__room",
308-
Prefetch(
309-
"slots__items",
310-
queryset=(
311-
ScheduleItemModel.objects.for_conference(self.id)
312-
.annotate(
313-
order=Case(
314-
When(type="custom", then=Value(1)),
315-
When(type="break", then=Value(1)),
316-
When(type="talk", then=Value(2)),
317-
When(type="panel", then=Value(3)),
318-
default=Value(4),
319-
output_field=IntegerField(),
320-
)
321-
)
322-
.order_by("order")
323-
.prefetch_related(
324-
"audience_level",
325-
"language",
326-
"rooms",
327-
"additional_speakers",
328-
"additional_speakers__user",
329-
"language",
330-
"submission",
331-
"submission__type",
332-
"submission__tags",
333-
"submission__duration",
334-
"submission__audience_level",
335-
"submission__speaker",
336-
"submission__languages",
337-
"submission__schedule_items",
338-
"keynote",
339-
"keynote__schedule_items",
340-
"keynote__schedule_items__rooms",
341-
"keynote__schedule_items__slot",
342-
"keynote__schedule_items__slot__day",
343-
"keynote__speakers",
344-
"keynote__speakers__user",
345-
)
346-
),
347-
),
348-
)
349-
.all()
350-
)
351-
all_speakers = [
352-
speaker.id
353-
for day in days
354-
for slot in day.slots.all()
355-
for item in slot.items.all()
356-
for speaker in item.speakers
357-
]
358-
info.context._participants_data = {
359-
participant.user_id: participant
360-
for participant in ParticipantModel.objects.for_conference(self.id)
361-
.filter(user_id__in=all_speakers)
362-
.prefetch_related("user")
363-
.all()
364-
}
365-
366-
return days
301+
return self.days.all()
367302

368303
@strawberry.field
369304
def current_day(self, info: Info) -> Day | None:

backend/api/schedule/types/day.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,18 @@
22
from schedule.models import ScheduleItem as ScheduleItemModel
33
from api.schedule.types.schedule_item import ScheduleItem
44
from django.utils import timezone
5-
from datetime import date, timedelta
5+
from datetime import timedelta
66
from api.schedule.types.day_room import DayRoom
77
from api.schedule.types.slot import ScheduleSlot
88
import strawberry
9+
import strawberry_django
10+
from schedule import models
911

1012

11-
@strawberry.type
13+
@strawberry_django.type(models.Day)
1214
class Day:
13-
id: strawberry.ID
14-
day: date
15+
id: strawberry.auto
16+
day: strawberry.auto
1517

1618
@strawberry.field
1719
def random_events(self, limit: int = 4) -> list[ScheduleItem]:
@@ -31,13 +33,13 @@ def random_events(self, limit: int = 4) -> list[ScheduleItem]:
3133
.order_by("?")[:limit]
3234
)
3335

34-
@strawberry.field
36+
@strawberry_django.field
3537
def slots(
3638
self, info: Info, room: strawberry.ID | None = None
3739
) -> list[ScheduleSlot]:
3840
if room:
39-
return list(self.slots.filter(items__rooms__id=room))
40-
return list(self.slots.all())
41+
return self.slots.filter(items__rooms__id=room)
42+
return self.slots.all()
4143

4244
@strawberry.field
4345
def running_events(self, info: Info) -> list[ScheduleItem]:
@@ -59,7 +61,7 @@ def running_events(self, info: Info) -> list[ScheduleItem]:
5961

6062
return [item for item in current_slot.items.all()]
6163

62-
@strawberry.field
64+
@strawberry_django.field(prefetch_related=["added_rooms__room"])
6365
def rooms(self) -> list[DayRoom]:
6466
added_rooms = self.added_rooms.all()
6567
return [

backend/api/schedule/types/room.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import strawberry
2+
import strawberry_django
3+
from schedule import models
24

35

4-
@strawberry.type
6+
@strawberry_django.type(models.Room)
57
class Room:
6-
id: strawberry.ID
7-
name: str
8+
id: strawberry.auto
9+
name: strawberry.auto
810
type: str

0 commit comments

Comments
 (0)