123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580 |
- import json
- import tempfile
- import uuid
- from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
- from django.contrib.contenttypes.models import ContentType
- from django.core.files.storage import FileSystemStorage
- from django.core.serializers.json import DjangoJSONEncoder
- from django.db import connection, models
- from django.db.models import F, Value
- from django.db.models.fields.files import ImageFieldFile
- from django.db.models.functions import Lower
- from django.utils.functional import SimpleLazyObject
- from django.utils.translation import gettext_lazy as _
- try:
- from PIL import Image
- except ImportError:
- Image = None
- test_collation = SimpleLazyObject(
- lambda: connection.features.test_collations["virtual"]
- )
- class Foo(models.Model):
- a = models.CharField(max_length=10)
- d = models.DecimalField(max_digits=5, decimal_places=3)
- def get_foo():
- return Foo.objects.get(id=1).pk
- class Bar(models.Model):
- b = models.CharField(max_length=10)
- a = models.ForeignKey(Foo, models.CASCADE, default=get_foo, related_name="bars")
- class Whiz(models.Model):
- CHOICES = {
- "Group 1": {
- 1: "First",
- 2: "Second",
- },
- "Group 2": (
- (3, "Third"),
- (4, "Fourth"),
- ),
- 0: "Other",
- 5: _("translated"),
- }
- c = models.IntegerField(choices=CHOICES, null=True)
- class WhizDelayed(models.Model):
- c = models.IntegerField(choices=(), null=True)
- WhizDelayed._meta.get_field("c").choices = Whiz.CHOICES
- class WhizIter(models.Model):
- c = models.IntegerField(choices=iter(Whiz.CHOICES.items()), null=True)
- class WhizIterEmpty(models.Model):
- c = models.CharField(choices=iter(()), blank=True, max_length=1)
- class Choiceful(models.Model):
- class Suit(models.IntegerChoices):
- DIAMOND = 1, "Diamond"
- SPADE = 2, "Spade"
- HEART = 3, "Heart"
- CLUB = 4, "Club"
- def get_choices():
- return [(i, str(i)) for i in range(3)]
- no_choices = models.IntegerField(null=True)
- empty_choices = models.IntegerField(choices=(), null=True)
- with_choices = models.IntegerField(choices=[(1, "A")], null=True)
- with_choices_dict = models.IntegerField(choices={1: "A"}, null=True)
- with_choices_nested_dict = models.IntegerField(
- choices={"Thing": {1: "A"}}, null=True
- )
- empty_choices_bool = models.BooleanField(choices=())
- empty_choices_text = models.TextField(choices=())
- choices_from_enum = models.IntegerField(choices=Suit)
- choices_from_iterator = models.IntegerField(choices=((i, str(i)) for i in range(3)))
- choices_from_callable = models.IntegerField(choices=get_choices)
- class BigD(models.Model):
- d = models.DecimalField(max_digits=32, decimal_places=30)
- class FloatModel(models.Model):
- size = models.FloatField()
- class BigS(models.Model):
- s = models.SlugField(max_length=255)
- class UnicodeSlugField(models.Model):
- s = models.SlugField(max_length=255, allow_unicode=True)
- class AutoModel(models.Model):
- value = models.AutoField(primary_key=True)
- class BigAutoModel(models.Model):
- value = models.BigAutoField(primary_key=True)
- class SmallAutoModel(models.Model):
- value = models.SmallAutoField(primary_key=True)
- class SmallIntegerModel(models.Model):
- value = models.SmallIntegerField()
- class IntegerModel(models.Model):
- value = models.IntegerField()
- class BigIntegerModel(models.Model):
- value = models.BigIntegerField()
- null_value = models.BigIntegerField(null=True, blank=True)
- class PositiveBigIntegerModel(models.Model):
- value = models.PositiveBigIntegerField()
- class PositiveSmallIntegerModel(models.Model):
- value = models.PositiveSmallIntegerField()
- class PositiveIntegerModel(models.Model):
- value = models.PositiveIntegerField()
- class Post(models.Model):
- title = models.CharField(max_length=100)
- body = models.TextField()
- class NullBooleanModel(models.Model):
- nbfield = models.BooleanField(null=True, blank=True)
- class BooleanModel(models.Model):
- bfield = models.BooleanField()
- class DateTimeModel(models.Model):
- d = models.DateField()
- dt = models.DateTimeField()
- t = models.TimeField()
- class DurationModel(models.Model):
- field = models.DurationField()
- class NullDurationModel(models.Model):
- field = models.DurationField(null=True)
- class PrimaryKeyCharModel(models.Model):
- string = models.CharField(max_length=10, primary_key=True)
- class FksToBooleans(models.Model):
- """Model with FKs to models with {Null,}BooleanField's, #15040"""
- bf = models.ForeignKey(BooleanModel, models.CASCADE)
- nbf = models.ForeignKey(NullBooleanModel, models.CASCADE)
- class FkToChar(models.Model):
- """Model with FK to a model with a CharField primary key, #19299"""
- out = models.ForeignKey(PrimaryKeyCharModel, models.CASCADE)
- class RenamedField(models.Model):
- modelname = models.IntegerField(name="fieldname", choices=((1, "One"),))
- class VerboseNameField(models.Model):
- id = models.AutoField("verbose pk", primary_key=True)
- field1 = models.BigIntegerField("verbose field1")
- field2 = models.BooleanField("verbose field2", default=False)
- field3 = models.CharField("verbose field3", max_length=10)
- field4 = models.DateField("verbose field4")
- field5 = models.DateTimeField("verbose field5")
- field6 = models.DecimalField("verbose field6", max_digits=6, decimal_places=1)
- field7 = models.EmailField("verbose field7")
- field8 = models.FileField("verbose field8", upload_to="unused")
- field9 = models.FilePathField("verbose field9")
- field10 = models.FloatField("verbose field10")
-
-
- field11 = models.IntegerField("verbose field11")
- field12 = models.GenericIPAddressField("verbose field12", protocol="ipv4")
- field13 = models.PositiveIntegerField("verbose field13")
- field14 = models.PositiveSmallIntegerField("verbose field14")
- field15 = models.SlugField("verbose field15")
- field16 = models.SmallIntegerField("verbose field16")
- field17 = models.TextField("verbose field17")
- field18 = models.TimeField("verbose field18")
- field19 = models.URLField("verbose field19")
- field20 = models.UUIDField("verbose field20")
- field21 = models.DurationField("verbose field21")
- class GenericIPAddress(models.Model):
- ip = models.GenericIPAddressField(null=True, protocol="ipv4")
- class DecimalLessThanOne(models.Model):
- d = models.DecimalField(max_digits=3, decimal_places=3)
- class FieldClassAttributeModel(models.Model):
- field_class = models.CharField
- class DataModel(models.Model):
- short_data = models.BinaryField(max_length=10, default=b"\x08")
- data = models.BinaryField()
- class Document(models.Model):
- myfile = models.FileField(upload_to="unused", unique=True)
- if Image:
- class TestImageFieldFile(ImageFieldFile):
- """
- Custom Field File class that records whether or not the underlying file
- was opened.
- """
- def __init__(self, *args, **kwargs):
- self.was_opened = False
- super().__init__(*args, **kwargs)
- def open(self):
- self.was_opened = True
- super().open()
- class TestImageField(models.ImageField):
- attr_class = TestImageFieldFile
-
- temp_storage_dir = tempfile.mkdtemp()
- temp_storage = FileSystemStorage(temp_storage_dir)
- class Person(models.Model):
- """
- Model that defines an ImageField with no dimension fields.
- """
- name = models.CharField(max_length=50)
- mugshot = TestImageField(storage=temp_storage, upload_to="tests")
- class AbstractPersonWithHeight(models.Model):
- """
- Abstract model that defines an ImageField with only one dimension field
- to make sure the dimension update is correctly run on concrete subclass
- instance post-initialization.
- """
- mugshot = TestImageField(
- storage=temp_storage, upload_to="tests", height_field="mugshot_height"
- )
- mugshot_height = models.PositiveSmallIntegerField()
- class Meta:
- abstract = True
- class PersonWithHeight(AbstractPersonWithHeight):
- """
- Concrete model that subclass an abstract one with only on dimension
- field.
- """
- name = models.CharField(max_length=50)
- class PersonWithHeightAndWidth(models.Model):
- """
- Model that defines height and width fields after the ImageField.
- """
- name = models.CharField(max_length=50)
- mugshot = TestImageField(
- storage=temp_storage,
- upload_to="tests",
- height_field="mugshot_height",
- width_field="mugshot_width",
- )
- mugshot_height = models.PositiveSmallIntegerField()
- mugshot_width = models.PositiveSmallIntegerField()
- class PersonDimensionsFirst(models.Model):
- """
- Model that defines height and width fields before the ImageField.
- """
- name = models.CharField(max_length=50)
- mugshot_height = models.PositiveSmallIntegerField()
- mugshot_width = models.PositiveSmallIntegerField()
- mugshot = TestImageField(
- storage=temp_storage,
- upload_to="tests",
- height_field="mugshot_height",
- width_field="mugshot_width",
- )
- class PersonTwoImages(models.Model):
- """
- Model that:
- * Defines two ImageFields
- * Defines the height/width fields before the ImageFields
- * Has a nullable ImageField
- """
- name = models.CharField(max_length=50)
- mugshot_height = models.PositiveSmallIntegerField()
- mugshot_width = models.PositiveSmallIntegerField()
- mugshot = TestImageField(
- storage=temp_storage,
- upload_to="tests",
- height_field="mugshot_height",
- width_field="mugshot_width",
- )
- headshot_height = models.PositiveSmallIntegerField(blank=True, null=True)
- headshot_width = models.PositiveSmallIntegerField(blank=True, null=True)
- headshot = TestImageField(
- blank=True,
- null=True,
- storage=temp_storage,
- upload_to="tests",
- height_field="headshot_height",
- width_field="headshot_width",
- )
- class CustomJSONDecoder(json.JSONDecoder):
- def __init__(self, object_hook=None, *args, **kwargs):
- return super().__init__(object_hook=self.as_uuid, *args, **kwargs)
- def as_uuid(self, dct):
- if "uuid" in dct:
- dct["uuid"] = uuid.UUID(dct["uuid"])
- return dct
- class JSONModel(models.Model):
- value = models.JSONField()
- class Meta:
- required_db_features = {"supports_json_field"}
- class NullableJSONModel(models.Model):
- value = models.JSONField(blank=True, null=True)
- value_custom = models.JSONField(
- encoder=DjangoJSONEncoder,
- decoder=CustomJSONDecoder,
- null=True,
- )
- class Meta:
- required_db_features = {"supports_json_field"}
- class RelatedJSONModel(models.Model):
- value = models.JSONField()
- json_model = models.ForeignKey(NullableJSONModel, models.CASCADE)
- class Meta:
- required_db_features = {"supports_json_field"}
- class AllFieldsModel(models.Model):
- big_integer = models.BigIntegerField()
- binary = models.BinaryField()
- boolean = models.BooleanField(default=False)
- char = models.CharField(max_length=10)
- date = models.DateField()
- datetime = models.DateTimeField()
- decimal = models.DecimalField(decimal_places=2, max_digits=2)
- duration = models.DurationField()
- email = models.EmailField()
- file_path = models.FilePathField()
- floatf = models.FloatField()
- integer = models.IntegerField()
- generic_ip = models.GenericIPAddressField()
- positive_integer = models.PositiveIntegerField()
- positive_small_integer = models.PositiveSmallIntegerField()
- slug = models.SlugField()
- small_integer = models.SmallIntegerField()
- text = models.TextField()
- time = models.TimeField()
- url = models.URLField()
- uuid = models.UUIDField()
- fo = models.ForeignObject(
- "self",
- on_delete=models.CASCADE,
- from_fields=["positive_integer"],
- to_fields=["id"],
- related_name="reverse",
- )
- fk = models.ForeignKey("self", models.CASCADE, related_name="reverse2")
- m2m = models.ManyToManyField("self")
- oto = models.OneToOneField("self", models.CASCADE)
- object_id = models.PositiveIntegerField()
- content_type = models.ForeignKey(ContentType, models.CASCADE)
- gfk = GenericForeignKey()
- gr = GenericRelation(DataModel)
- class ManyToMany(models.Model):
- m2m = models.ManyToManyField("self")
- class UUIDModel(models.Model):
- field = models.UUIDField()
- class NullableUUIDModel(models.Model):
- field = models.UUIDField(blank=True, null=True)
- class PrimaryKeyUUIDModel(models.Model):
- id = models.UUIDField(primary_key=True, default=uuid.uuid4)
- class RelatedToUUIDModel(models.Model):
- uuid_fk = models.ForeignKey("PrimaryKeyUUIDModel", models.CASCADE)
- class UUIDChild(PrimaryKeyUUIDModel):
- pass
- class UUIDGrandchild(UUIDChild):
- pass
- class GeneratedModel(models.Model):
- a = models.IntegerField()
- b = models.IntegerField()
- field = models.GeneratedField(
- expression=F("a") + F("b"),
- output_field=models.IntegerField(),
- db_persist=True,
- )
- class Meta:
- required_db_features = {"supports_stored_generated_columns"}
- class GeneratedModelVirtual(models.Model):
- a = models.IntegerField()
- b = models.IntegerField()
- field = models.GeneratedField(
- expression=F("a") + F("b"),
- output_field=models.IntegerField(),
- db_persist=False,
- )
- class Meta:
- required_db_features = {"supports_virtual_generated_columns"}
- class GeneratedModelParams(models.Model):
- field = models.GeneratedField(
- expression=Value("Constant", output_field=models.CharField(max_length=10)),
- output_field=models.CharField(max_length=10),
- db_persist=True,
- )
- class Meta:
- required_db_features = {"supports_stored_generated_columns"}
- class GeneratedModelParamsVirtual(models.Model):
- field = models.GeneratedField(
- expression=Value("Constant", output_field=models.CharField(max_length=10)),
- output_field=models.CharField(max_length=10),
- db_persist=False,
- )
- class Meta:
- required_db_features = {"supports_virtual_generated_columns"}
- class GeneratedModelOutputFieldDbCollation(models.Model):
- name = models.CharField(max_length=10)
- lower_name = models.GeneratedField(
- expression=Lower("name"),
- output_field=models.CharField(db_collation=test_collation, max_length=11),
- db_persist=True,
- )
- class Meta:
- required_db_features = {"supports_stored_generated_columns"}
- class GeneratedModelOutputFieldDbCollationVirtual(models.Model):
- name = models.CharField(max_length=10)
- lower_name = models.GeneratedField(
- expression=Lower("name"),
- db_persist=False,
- output_field=models.CharField(db_collation=test_collation, max_length=11),
- )
- class Meta:
- required_db_features = {"supports_virtual_generated_columns"}
- class GeneratedModelNull(models.Model):
- name = models.CharField(max_length=10, null=True)
- lower_name = models.GeneratedField(
- expression=Lower("name"),
- output_field=models.CharField(max_length=10),
- db_persist=True,
- null=True,
- )
- class Meta:
- required_db_features = {"supports_stored_generated_columns"}
- class GeneratedModelNullVirtual(models.Model):
- name = models.CharField(max_length=10, null=True)
- lower_name = models.GeneratedField(
- expression=Lower("name"),
- output_field=models.CharField(max_length=10),
- db_persist=False,
- null=True,
- )
- class Meta:
- required_db_features = {"supports_virtual_generated_columns"}
|