Skip to content

Instantly share code, notes, and snippets.

@dmwyatt
Created August 31, 2024 17:31
Show Gist options
  • Save dmwyatt/725a28d97ee216e6908ce4d3c3d45b9c to your computer and use it in GitHub Desktop.
Save dmwyatt/725a28d97ee216e6908ce4d3c3d45b9c to your computer and use it in GitHub Desktop.
blue/green django
# models.py
from django.db import models
class User(models.Model):
# Old field (blue version)
name = models.CharField(max_length=100)
# New fields (green version)
first_name = models.CharField(max_length=50, null=True, blank=True)
last_name = models.CharField(max_length=50, null=True, blank=True)
email = models.EmailField(unique=True)
# migrations/0002_expand_user_model.py
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('yourapp', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='User',
name='first_name',
field=models.CharField(max_length=50, null=True, blank=True),
),
migrations.AddField(
model_name='User',
name='last_name',
field=models.CharField(max_length=50, null=True, blank=True),
),
]
# migrations/0003_populate_new_name_fields.py
from django.db import migrations
def split_name(apps, schema_editor):
User = apps.get_model('yourapp', 'User')
for user in User.objects.all():
names = user.name.split(' ', 1)
user.first_name = names[0]
user.last_name = names[1] if len(names) > 1 else ''
user.save()
class Migration(migrations.Migration):
dependencies = [
('yourapp', '0002_expand_user_model'),
]
operations = [
migrations.RunPython(split_name),
]
# views.py
from django.conf import settings
from .models import User
def get_user_name(user):
if settings.USE_NEW_NAME_FIELDS:
return f"{user.first_name} {user.last_name}".strip()
return user.name
def create_user(data):
user = User(
name=f"{data['first_name']} {data['last_name']}".strip(),
email=data['email']
)
if settings.USE_NEW_NAME_FIELDS:
user.first_name = data['first_name']
user.last_name = data['last_name']
user.save()
return user
# settings.py
# Feature flag to control which version is active
USE_NEW_NAME_FIELDS = False # Set to True for green environment
# Blue/Green deployment settings
BLUE_GREEN_DEPLOYMENT = True
DEPLOYMENT_COLOR = 'blue' # Change to 'green' for green environment
# middleware.py
from django.conf import settings
class BlueGreenMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
if settings.BLUE_GREEN_DEPLOYMENT:
request.session['deployment_color'] = settings.DEPLOYMENT_COLOR
return self.get_response(request)
# wsgi_blue.py and wsgi_green.py
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'yourproject.settings')
os.environ['DEPLOYMENT_COLOR'] = 'blue' # or 'green' for wsgi_green.py
application = get_wsgi_application()
# nginx.conf (example configuration)
upstream blue {
server unix:/path/to/blue.sock;
}
upstream green {
server unix:/path/to/green.sock;
}
server {
listen 80;
server_name yourdomain.com;
location / {
proxy_pass http://blue; # Change to green when ready
}
}
# migrations/0004_remove_name_field.py (Apply after full transition to green)
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('yourapp', '0003_populate_new_name_fields'),
]
operations = [
migrations.RemoveField(
model_name='User',
name='name',
),
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment