Skip to content

Commit 16cfe53

Browse files
committed
fix: #196 fix learner unique constraint
1 parent 4f6eeb7 commit 16cfe53

3 files changed

Lines changed: 47 additions & 3 deletions

File tree

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Generated by Django 6.0.1 on 2026-02-02 08:56
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
dependencies = [
8+
("django_email_learning", "0005_course_image_alter_apikey_salt_and_more"),
9+
]
10+
11+
operations = [
12+
migrations.AlterField(
13+
model_name="apikey",
14+
name="salt",
15+
field=models.CharField(
16+
default="9a60f001297443b3b6ac8d6cc7754ca6",
17+
editable=False,
18+
max_length=32,
19+
),
20+
),
21+
migrations.AlterField(
22+
model_name="imapconnection",
23+
name="salt",
24+
field=models.CharField(
25+
default="9a60f001297443b3b6ac8d6cc7754ca6",
26+
editable=False,
27+
max_length=32,
28+
),
29+
),
30+
migrations.AlterField(
31+
model_name="learner",
32+
name="email",
33+
field=models.EmailField(max_length=254),
34+
),
35+
migrations.AlterUniqueTogether(
36+
name="learner",
37+
unique_together={("organization", "email")},
38+
),
39+
]

django_email_learning/models.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -424,14 +424,17 @@ def save(self, *args, **kwargs) -> None: # type: ignore[no-untyped-def]
424424

425425
class Learner(models.Model):
426426
organization = models.ForeignKey(Organization, on_delete=models.CASCADE)
427-
email = models.EmailField(unique=True)
427+
email = models.EmailField()
428428
created_at = models.DateTimeField(auto_now_add=True)
429429

430430
def save(self, *args, **kwargs) -> None: # type: ignore[no-untyped-def]
431431
self.email = self.email.lower()
432432
self.full_clean()
433433
super().save(*args, **kwargs)
434434

435+
class Meta:
436+
unique_together = [["organization", "email"]]
437+
435438

436439
class Enrollment(models.Model):
437440
state_transitions = {

tests/test_models/test_learner.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,13 @@ def test_learner_email_case_insensitivity(db):
2222
assert learner.email == "user@example.com"
2323

2424

25-
def test_learner_unique_email_constraint(db):
25+
def test_learner_unique_together_email_constraint(db):
2626
Learner.objects.create(email="user@example.com", organization_id=1)
2727
with pytest.raises(ValidationError) as exc_info:
2828
Learner.objects.create(email="USER@EXAMPLE.COM", organization_id=1)
29-
assert "Learner with this Email already exists." in str(exc_info.value)
29+
assert "Learner with this Organization and Email already exists." in str(
30+
exc_info.value
31+
)
3032
learner_count = Learner.objects.filter(
3133
email__iexact="user@example.com", organization_id=1
3234
).count()

0 commit comments

Comments
 (0)