Skip to content

Commit 33e042e

Browse files
committed
✨ feat: add development environment configuration and update sample data generation
1 parent e811ab8 commit 33e042e

File tree

6 files changed

+98
-46
lines changed

6 files changed

+98
-46
lines changed

README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ Website for Python Ireland (python.ie / pycon.ie) community, built with Django 6
3030

3131
4. Generate sample data (creates pages, navigation, meetups):
3232
```bash
33-
docker compose run --rm web python pythonie/manage.py generate_sample_data --settings=pythonie.settings.dev
33+
task django:generate-sample-data
34+
# or: docker compose run --rm web python pythonie/manage.py generate_sample_data --settings=pythonie.settings.dev
3435
```
3536

3637
5. Create a superuser:
@@ -58,7 +59,7 @@ If you prefer to develop without Docker:
5859
5. Activate the virtualenv: `source pythonie-venv/bin/activate`
5960
6. Install dependencies: `pip install -r requirements.txt` (or `uv pip install -r requirements.txt`)
6061
7. Set up the database: `python pythonie/manage.py migrate --settings=pythonie.settings.dev`
61-
8. Generate sample data: `python pythonie/manage.py generate_sample_data --settings=pythonie.settings.dev`
62+
8. Generate sample data: `task django:generate-sample-data` (or `python pythonie/manage.py generate_sample_data --settings=pythonie.settings.dev`)
6263
9. Create a superuser: `python pythonie/manage.py createsuperuser --settings=pythonie.settings.dev`
6364
10. Install and run Redis server locally: `redis-server`
6465
11. Set Redis environment variable: `export REDISCLOUD_URL=127.0.0.1:6379`
@@ -95,7 +96,7 @@ task django:make-migrations # Create new migrations
9596
task django:collect-static # Collect static files
9697

9798
# Sample Data (for development)
98-
python pythonie/manage.py generate_sample_data --settings=pythonie.settings.dev
99+
task django:generate-sample-data
99100

100101
# Testing
101102
task tests # Run test suite

Taskfile.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,16 @@ tasks:
145145
cmds:
146146
- docker compose run --rm web python pythonie/manage.py collectstatic
147147

148+
django:generate-sample-data:
149+
desc: Generate sample data for development
150+
cmds:
151+
- |
152+
if command -v docker >/dev/null 2>&1 && docker ps >/dev/null 2>&1; then
153+
docker compose run --rm web python pythonie/manage.py generate_sample_data
154+
else
155+
python pythonie/manage.py generate_sample_data --settings=pythonie.settings.dev
156+
fi
157+
148158
dependencies:compute:
149159
desc: Compute the dependencies
150160
cmds:

development.env

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
DJANGO_SETTINGS_MODULE=pythonie.settings.dev
2+
PGDATABASE=pythonie
3+
PGUSER=postgres
4+
PGPASSWORD=pythonie
5+
PGHOST=postgres
6+
REDISCLOUD_URL=redis://redis:6379
7+

pythonie/core/factories.py

Lines changed: 40 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,38 @@
1-
import factory
21
from django.utils import timezone
3-
from factory.django import DjangoModelFactory
4-
from meetups.models import Meetup
5-
from sponsors.models import SponsorshipLevel
2+
import wagtail_factories
63

74
from core.models import HomePage, SimplePage
5+
from meetups.models import Meetup
6+
from sponsors.models import SponsorshipLevel
87

9-
10-
class SponsorshipLevelFactory(DjangoModelFactory):
11-
class Meta:
12-
model = SponsorshipLevel
13-
django_get_or_create = ("name",)
14-
15-
level = 100
16-
name = "Bronze"
17-
18-
19-
class MeetupFactory(DjangoModelFactory):
20-
class Meta:
21-
model = Meetup
22-
django_get_or_create = ("id",)
23-
24-
id = factory.Sequence(lambda n: f"meetup-{n}")
25-
name = "Python Ireland Meetup"
26-
description = "Monthly Python meetup in Dublin"
27-
event_url = "https://meetup.com/pythonireland/"
28-
time = factory.LazyFunction(lambda: timezone.now() + timezone.timedelta(days=30))
29-
created = factory.LazyFunction(timezone.now)
30-
rsvps = 50
31-
status = "upcoming"
32-
visibility = "public"
33-
34-
35-
class HomePageFactory(DjangoModelFactory):
8+
def create_sponsorship_level(name="Bronze", level=100):
9+
return SponsorshipLevel.objects.get_or_create(name=name, defaults={"level": level})[0]
10+
11+
12+
def create_meetup(id, name="Python Ireland Meetup", description="Monthly Python meetup in Dublin",
13+
event_url="https://meetup.com/pythonireland/", time=None, created=None,
14+
rsvps=50, status="upcoming", visibility="public"):
15+
if time is None:
16+
time = timezone.now() + timezone.timedelta(days=30)
17+
if created is None:
18+
created = timezone.now()
19+
20+
return Meetup.objects.get_or_create(
21+
id=id,
22+
defaults={
23+
"name": name,
24+
"description": description,
25+
"event_url": event_url,
26+
"time": time,
27+
"created": created,
28+
"rsvps": rsvps,
29+
"status": status,
30+
"visibility": visibility,
31+
}
32+
)[0]
33+
34+
35+
class HomePageFactory(wagtail_factories.PageFactory):
3636
class Meta:
3737
model = HomePage
3838

@@ -42,10 +42,18 @@ class Meta:
4242
body = []
4343

4444

45-
class SimplePageFactory(DjangoModelFactory):
45+
class SimplePageFactory(wagtail_factories.PageFactory):
4646
class Meta:
4747
model = SimplePage
4848

4949
title = "Sample Page"
5050
slug = "sample-page"
5151
body = []
52+
53+
54+
def SponsorshipLevelFactory(name="Bronze", level=100):
55+
return create_sponsorship_level(name=name, level=level)
56+
57+
58+
def MeetupFactory(id, name="Python Ireland Meetup", **kwargs):
59+
return create_meetup(id=id, name=name, **kwargs)

pythonie/core/management/commands/generate_sample_data.py

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -41,23 +41,46 @@ def _create_home_page(self):
4141
self.stdout.write("Home page already exists")
4242
return home
4343

44-
wagtail_root = Page.objects.get(depth=1)
44+
try:
45+
wagtail_root = Page.objects.get(depth=1)
46+
except Page.DoesNotExist:
47+
from wagtail.models import Locale
48+
locale, _ = Locale.objects.get_or_create(language_code="en")
49+
wagtail_root = Page.add_root(
50+
instance=Page(title="Root", slug="root", locale=locale)
51+
)
52+
self.stdout.write("Created Wagtail root page")
53+
4554
default_home_exists = Page.objects.filter(slug="home", depth=2).exists()
4655
slug = "python-ireland" if default_home_exists else "home"
4756

48-
home = HomePageFactory.build(
57+
home = HomePageFactory(
58+
parent=wagtail_root,
4959
slug=slug,
5060
show_in_menus=True,
5161
body=self._get_home_content(),
5262
)
53-
wagtail_root.add_child(instance=home)
54-
self.stdout.write(self.style.SUCCESS("Created home page"))
55-
56-
site = Site.objects.filter(is_default_site=True).first()
57-
if site:
63+
# Publish the home page
64+
revision = home.save_revision()
65+
revision.publish()
66+
self.stdout.write(self.style.SUCCESS("Created and published home page"))
67+
68+
# Create or update the default site
69+
site, created = Site.objects.get_or_create(
70+
is_default_site=True,
71+
defaults={
72+
"hostname": "localhost",
73+
"port": 8000,
74+
"site_name": "Python Ireland",
75+
"root_page": home,
76+
}
77+
)
78+
if not created:
5879
site.root_page = home
5980
site.save()
6081
self.stdout.write(self.style.SUCCESS("Updated site root page"))
82+
else:
83+
self.stdout.write(self.style.SUCCESS("Created default site"))
6184

6285
return home
6386

@@ -88,10 +111,13 @@ def _create_page(self, parent, title, slug, body=None):
88111
self.stdout.write(f" {title} already exists")
89112
return SimplePage.objects.get(slug=slug)
90113

91-
page = SimplePageFactory.build(
92-
title=title, slug=slug, body=body or [], show_in_menus=True
114+
page = SimplePageFactory(
115+
parent=parent,
116+
title=title,
117+
slug=slug,
118+
body=body or [],
119+
show_in_menus=True,
93120
)
94-
parent.add_child(instance=page)
95121
self.stdout.write(self.style.SUCCESS(f"Created {title}"))
96122
return page
97123

requirements/dev.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
-c main.txt
33
coverage
44
django-debug-toolbar
5-
factory-boy
5+
wagtail-factories
66
fakeredis
77
isort
88
model_mommy

0 commit comments

Comments
 (0)