Files
mizan/django/tests/models.py
Ryth Azhur 9516c05f75 Add shapes tests and fix django-readers as core dependency
25 tests covering Shape, Diff, and NestedDiff:
- Shape metaclass: model resolution, field extraction, nested detection, spec/pair building
- Query: list, filter, nested relations, empty results, Pydantic serialization
- Diff (new): detects all fields as changed
- Diff (existing): no changes, single field, multiple fields, nonexistent ID
- Diff (nested): created, updated, deleted, combined, nonexistent relation

Fixes:
- django-readers moved from optional to core dependency
- Shape import lazy-loaded via __getattr__ (django_readers imports
  contenttypes which can't happen during apps.populate())
- Added Author, Book, Tag test models

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 02:16:36 -04:00

75 lines
2.2 KiB
Python

from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, PermissionsMixin
from django.db import models
class EmailUserManager(BaseUserManager):
"""Custom user manager using email as the unique identifier."""
def create_user(self, email, password=None, **extra_fields):
if not email:
raise ValueError("Email is required")
email = self.normalize_email(email)
user = self.model(email=email, **extra_fields)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email, password=None, **extra_fields):
extra_fields.setdefault("is_staff", True)
extra_fields.setdefault("is_superuser", True)
return self.create_user(email, password, **extra_fields)
class EmailUser(AbstractBaseUser, PermissionsMixin):
"""Minimal user model with email as USERNAME_FIELD.
Matches the calling convention used in djarea's test suite:
User.objects.create_user(email="...", password="...", is_staff=True)
"""
email = models.EmailField(unique=True)
is_staff = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
objects = EmailUserManager()
USERNAME_FIELD = "email"
REQUIRED_FIELDS = []
class Meta:
app_label = "tests"
# ─── Shape test models ──────────────────────────────────────────────────────
class Author(models.Model):
name = models.CharField(max_length=100)
bio = models.TextField(blank=True, default="")
class Meta:
app_label = "tests"
def __str__(self):
return self.name
class Book(models.Model):
title = models.CharField(max_length=200)
pages = models.IntegerField(default=0)
author = models.ForeignKey(Author, on_delete=models.CASCADE, related_name="books")
class Meta:
app_label = "tests"
def __str__(self):
return self.title
class Tag(models.Model):
name = models.CharField(max_length=50)
books = models.ManyToManyField(Book, related_name="tags", blank=True)
class Meta:
app_label = "tests"