1+ import datetime
2+ from django .conf import settings
3+ from django .core .management .base import BaseCommand , CommandError
4+ from django .utils import timezone
5+ from events .models import Calendar , Event , EventCategory , EventLocation , OccurringRule , RecurringRule
6+ from dateutil .rrule import WEEKLY , MONTHLY , YEARLY , DAILY
7+
8+
9+ class Command (BaseCommand ):
10+ help = 'Creates test events for the events app (development only)'
11+
12+ def add_arguments (self , parser ):
13+ parser .add_argument (
14+ '--force' ,
15+ action = 'store_true' ,
16+ help = 'Force execution even in non-DEBUG mode (use with extreme caution)' ,
17+ )
18+
19+ def handle (self , * args , ** options ):
20+ # Production safety check
21+ if not settings .DEBUG and not options ['force' ]:
22+ raise CommandError (
23+ "This command cannot be run in production (DEBUG=False). "
24+ "This command creates test data and should only be used in development environments."
25+ )
26+ # Create main calendar
27+ main_calendar , created = Calendar .objects .get_or_create (
28+ slug = 'python-events' ,
29+ defaults = {
30+ 'name' : 'Python Events' ,
31+ 'description' : 'Main Python community events calendar' ,
32+ }
33+ )
34+ self .stdout .write (f"Main calendar { 'created' if created else 'already exists' } : { main_calendar } " )
35+
36+ # Create additional calendars
37+ user_group_calendar , _ = Calendar .objects .get_or_create (
38+ slug = 'user-group-events' ,
39+ defaults = {
40+ 'name' : 'User Group Events' ,
41+ 'description' : 'Python user group meetups and events' ,
42+ }
43+ )
44+
45+ conference_calendar , _ = Calendar .objects .get_or_create (
46+ slug = 'conferences' ,
47+ defaults = {
48+ 'name' : 'Python Conferences' ,
49+ 'description' : 'Major Python conferences worldwide' ,
50+ }
51+ )
52+
53+ # Create categories
54+ meetup_category , _ = EventCategory .objects .get_or_create (
55+ slug = 'meetup' ,
56+ calendar = main_calendar ,
57+ defaults = {'name' : 'Meetup' }
58+ )
59+
60+ conference_category , _ = EventCategory .objects .get_or_create (
61+ slug = 'conference' ,
62+ calendar = main_calendar ,
63+ defaults = {'name' : 'Conference' }
64+ )
65+
66+ workshop_category , _ = EventCategory .objects .get_or_create (
67+ slug = 'workshop' ,
68+ calendar = main_calendar ,
69+ defaults = {'name' : 'Workshop' }
70+ )
71+
72+ sprint_category , _ = EventCategory .objects .get_or_create (
73+ slug = 'sprint' ,
74+ calendar = main_calendar ,
75+ defaults = {'name' : 'Sprint' }
76+ )
77+
78+ # Create locations
79+ location_sf , _ = EventLocation .objects .get_or_create (
80+ name = 'San Francisco Python Meetup Space' ,
81+ calendar = main_calendar ,
82+ defaults = {
83+ 'address' : '123 Market St, San Francisco, CA 94105' ,
84+ 'url' : 'https://example.com/sf-venue'
85+ }
86+ )
87+
88+ location_ny , _ = EventLocation .objects .get_or_create (
89+ name = 'NYC Python Center' ,
90+ calendar = main_calendar ,
91+ defaults = {
92+ 'address' : '456 Broadway, New York, NY 10013' ,
93+ 'url' : 'https://example.com/ny-venue'
94+ }
95+ )
96+
97+ location_london , _ = EventLocation .objects .get_or_create (
98+ name = 'London Tech Hub' ,
99+ calendar = main_calendar ,
100+ defaults = {
101+ 'address' : '789 Oxford Street, London, UK' ,
102+ 'url' : 'https://example.com/london-venue'
103+ }
104+ )
105+
106+ location_online , _ = EventLocation .objects .get_or_create (
107+ name = 'Online' ,
108+ calendar = main_calendar ,
109+ defaults = {
110+ 'address' : '' ,
111+ 'url' : 'https://zoom.us'
112+ }
113+ )
114+
115+ # Current time reference
116+ now = timezone .now ()
117+
118+ # Create past, current, and future events
119+
120+ # 1. Past conference (3 months ago)
121+ past_event = Event .objects .create (
122+ title = 'PyCon US 2024' ,
123+ calendar = conference_calendar ,
124+ description = 'The largest annual gathering for the Python community.' ,
125+ venue = location_sf ,
126+ featured = True
127+ )
128+ past_event .categories .add (conference_category )
129+ OccurringRule .objects .create (
130+ event = past_event ,
131+ dt_start = now - timezone .timedelta (days = 90 ),
132+ dt_end = now - timezone .timedelta (days = 87 )
133+ )
134+
135+ # 2. Ongoing workshop series (weekly)
136+ workshop_event = Event .objects .create (
137+ title = 'Python for Data Science Workshop' ,
138+ calendar = main_calendar ,
139+ description = 'Weekly hands-on workshop covering pandas, numpy, and data visualization.' ,
140+ venue = location_online
141+ )
142+ workshop_event .categories .add (workshop_category )
143+ RecurringRule .objects .create (
144+ event = workshop_event ,
145+ begin = now - timezone .timedelta (days = 30 ),
146+ finish = now + timezone .timedelta (days = 90 ),
147+ duration = '2 hours' ,
148+ interval = 1 ,
149+ frequency = WEEKLY
150+ )
151+
152+ # 3. Monthly user group meetup
153+ meetup_event = Event .objects .create (
154+ title = 'NYC Python Meetup' ,
155+ calendar = user_group_calendar ,
156+ description = 'Monthly gathering of Python enthusiasts in New York City. Lightning talks and networking.' ,
157+ venue = location_ny
158+ )
159+ meetup_event .categories .add (meetup_category )
160+ RecurringRule .objects .create (
161+ event = meetup_event ,
162+ begin = now - timezone .timedelta (days = 60 ),
163+ finish = now + timezone .timedelta (days = 365 ),
164+ duration = '3 hours' ,
165+ interval = 1 ,
166+ frequency = MONTHLY
167+ )
168+
169+ # 4. Upcoming sprint (next week)
170+ sprint_event = Event .objects .create (
171+ title = 'Django Sprint Weekend' ,
172+ calendar = main_calendar ,
173+ description = 'Two-day sprint to contribute to Django core and ecosystem packages.' ,
174+ venue = location_sf
175+ )
176+ sprint_event .categories .add (sprint_category )
177+ OccurringRule .objects .create (
178+ event = sprint_event ,
179+ dt_start = now + timezone .timedelta (days = 7 ),
180+ dt_end = now + timezone .timedelta (days = 9 )
181+ )
182+
183+ # 5. Major upcoming conference
184+ pycon_europe = Event .objects .create (
185+ title = 'EuroPython 2025' ,
186+ calendar = conference_calendar ,
187+ description = 'The official European Python conference bringing together Python users from across Europe and beyond.' ,
188+ venue = location_london ,
189+ featured = True
190+ )
191+ pycon_europe .categories .add (conference_category )
192+ OccurringRule .objects .create (
193+ event = pycon_europe ,
194+ dt_start = now + timezone .timedelta (days = 120 ),
195+ dt_end = now + timezone .timedelta (days = 125 )
196+ )
197+
198+ # 6. Daily coding challenge (for next 30 days)
199+ daily_challenge = Event .objects .create (
200+ title = 'Python Daily Coding Challenge' ,
201+ calendar = main_calendar ,
202+ description = 'Solve a new Python coding challenge every day. Perfect for interview prep!' ,
203+ venue = location_online
204+ )
205+ daily_challenge .categories .add (workshop_category )
206+ RecurringRule .objects .create (
207+ event = daily_challenge ,
208+ begin = now ,
209+ finish = now + timezone .timedelta (days = 30 ),
210+ duration = '1 hour' ,
211+ interval = 1 ,
212+ frequency = DAILY
213+ )
214+
215+ # 7. London Python meetup (monthly)
216+ london_meetup = Event .objects .create (
217+ title = 'London Python User Group' ,
218+ calendar = user_group_calendar ,
219+ description = 'Monthly meetup for Pythonistas in London. Talks, tutorials, and pub discussions.' ,
220+ venue = location_london
221+ )
222+ london_meetup .categories .add (meetup_category )
223+ RecurringRule .objects .create (
224+ event = london_meetup ,
225+ begin = now - timezone .timedelta (days = 45 ),
226+ finish = now + timezone .timedelta (days = 180 ),
227+ duration = '2 hours 30 min' ,
228+ interval = 1 ,
229+ frequency = MONTHLY
230+ )
231+
232+ # 8. Annual Python conference
233+ pydata_global = Event .objects .create (
234+ title = 'PyData Global Conference' ,
235+ calendar = conference_calendar ,
236+ description = 'The global conference on data science, machine learning, and AI with Python.' ,
237+ venue = location_online ,
238+ featured = True
239+ )
240+ pydata_global .categories .add (conference_category )
241+ OccurringRule .objects .create (
242+ event = pydata_global ,
243+ dt_start = now + timezone .timedelta (days = 60 ),
244+ dt_end = now + timezone .timedelta (days = 63 ),
245+ all_day = True
246+ )
247+
248+ # 9. Weekend workshop
249+ ml_workshop = Event .objects .create (
250+ title = 'Machine Learning with Python: From Zero to Hero' ,
251+ calendar = main_calendar ,
252+ description = 'Intensive weekend workshop covering ML fundamentals with scikit-learn and TensorFlow.' ,
253+ venue = location_sf
254+ )
255+ ml_workshop .categories .add (workshop_category )
256+ OccurringRule .objects .create (
257+ event = ml_workshop ,
258+ dt_start = now + timezone .timedelta (days = 14 ),
259+ dt_end = now + timezone .timedelta (days = 16 )
260+ )
261+
262+ # 10. Recurring online office hours
263+ office_hours = Event .objects .create (
264+ title = 'Python Core Dev Office Hours' ,
265+ calendar = main_calendar ,
266+ description = 'Weekly office hours with Python core developers. Get your questions answered!' ,
267+ venue = location_online
268+ )
269+ RecurringRule .objects .create (
270+ event = office_hours ,
271+ begin = now - timezone .timedelta (days = 14 ),
272+ finish = now + timezone .timedelta (days = 90 ),
273+ duration = '1 hour' ,
274+ interval = 1 ,
275+ frequency = WEEKLY
276+ )
277+
278+ self .stdout .write (self .style .SUCCESS (f'Successfully created test events across { Calendar .objects .count ()} calendars' ))
279+ self .stdout .write (f'Total events: { Event .objects .count ()} ' )
280+ self .stdout .write (f'Featured events: { Event .objects .filter (featured = True ).count ()} ' )
281+ self .stdout .write (f'Events with recurring rules: { Event .objects .filter (recurring_rules__isnull = False ).distinct ().count ()} ' )
282+ self .stdout .write (f'Events with single occurrences: { Event .objects .filter (occurring_rule__isnull = False ).count ()} ' )
0 commit comments