Repository: cookiecutter/cookiecutter-django

Issue:
duplicate key value violates unique constraint "django_site_pkey"
### Discussed in https://github.com/cookiecutter/cookiecutter-django/discussions/3506

<div type='discussions-op-text'>

<sup>Originally posted by **lionelwust** January  2, 2022</sup>
Hello Guys,

I've been running a django project based on cookie-cutter-django for a while.

Now, I'm trying to run 2 domains with the same project, so same DB and apps, but different urls and allowed_hosts. I am currently setting this up on pythonanywhere and in the meantime, I wanted to already add the second domain as a Site instance, in order to be able to use the Sites framework down the line.

But I got a duplicate key values error when trying to do that. The first Site instance has been created by the original cookie cutter migration. Did you already experience this behaviour and is there an obvious answer to that ?

Thanks a lot in advance !!
Lionel</div>


Discussion:
Let's discuss in the original discussion, no need to duplicate threads.

Resolving patch:
diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/contrib/sites/migrations/0003_set_site_domain_and_name.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/contrib/sites/migrations/0003_set_site_domain_and_name.py
--- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/contrib/sites/migrations/0003_set_site_domain_and_name.py
+++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/contrib/sites/migrations/0003_set_site_domain_and_name.py
@@ -7,23 +7,52 @@
 from django.db import migrations
 
 
-def update_site_forward(apps, schema_editor):
-    """Set site domain and name."""
-    Site = apps.get_model("sites", "Site")
-    Site.objects.update_or_create(
+def _update_or_create_site_with_sequence(site_model, connection, domain, name):
+    """Update or create the site with default ID and keep the DB sequence in sync."""
+    site, created = site_model.objects.update_or_create(
         id=settings.SITE_ID,
         defaults={
-            "domain": "{{cookiecutter.domain_name}}",
-            "name": "{{cookiecutter.project_name}}",
+            "domain": domain,
+            "name": name,
         },
     )
+    if created:
+        # We provided the ID explicitly when creating the Site entry, therefore the DB
+        # sequence to auto-generate them wasn't used and is now out of sync. If we
+        # don't do anything, we'll get a unique constraint violation the next time a
+        # site is created.
+        # To avoid this, we need to manually update DB sequence and make sure it's
+        # greater than the maximum value.
+        max_id = site_model.objects.order_by('-id').first().id
+        with connection.cursor() as cursor:
+            cursor.execute("SELECT last_value from django_site_id_seq")
+            (current_id,) = cursor.fetchone()
+            if current_id <= max_id:
+                cursor.execute(
+                    "alter sequence django_site_id_seq restart with %s",
+                    [max_id + 1],
+                )
+
+
+def update_site_forward(apps, schema_editor):
+    """Set site domain and name."""
+    Site = apps.get_model("sites", "Site")
+    _update_or_create_site_with_sequence(
+        Site,
+        schema_editor.connection,
+        "{{cookiecutter.domain_name}}",
+        "{{cookiecutter.project_name}}",
+    )
 
 
 def update_site_backward(apps, schema_editor):
     """Revert site domain and name to default."""
     Site = apps.get_model("sites", "Site")
-    Site.objects.update_or_create(
-        id=settings.SITE_ID, defaults={"domain": "example.com", "name": "example.com"}
+    _update_or_create_site_with_sequence(
+        Site,
+        schema_editor.connection,
+        "example.com",
+        "example.com",
     )
 
 


Test patch: