Created
August 31, 2024 17:31
-
-
Save dmwyatt/725a28d97ee216e6908ce4d3c3d45b9c to your computer and use it in GitHub Desktop.
blue/green django
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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