models.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  1. import os
  2. import tempfile
  3. import uuid
  4. from django.contrib.contenttypes.fields import (
  5. GenericForeignKey, GenericRelation,
  6. )
  7. from django.contrib.contenttypes.models import ContentType
  8. from django.core.files.storage import FileSystemStorage
  9. from django.db import models
  10. from django.db.models.fields.files import ImageField, ImageFieldFile
  11. from django.db.models.fields.related import (
  12. ForeignKey, ForeignObject, ManyToManyField, OneToOneField,
  13. )
  14. try:
  15. from PIL import Image
  16. except ImportError:
  17. Image = None
  18. class Foo(models.Model):
  19. a = models.CharField(max_length=10)
  20. d = models.DecimalField(max_digits=5, decimal_places=3)
  21. def get_foo():
  22. return Foo.objects.get(id=1).pk
  23. class Bar(models.Model):
  24. b = models.CharField(max_length=10)
  25. a = models.ForeignKey(Foo, models.CASCADE, default=get_foo, related_name='bars')
  26. class Whiz(models.Model):
  27. CHOICES = (
  28. ('Group 1', (
  29. (1, 'First'),
  30. (2, 'Second'),
  31. )
  32. ),
  33. ('Group 2', (
  34. (3, 'Third'),
  35. (4, 'Fourth'),
  36. )
  37. ),
  38. (0, 'Other'),
  39. )
  40. c = models.IntegerField(choices=CHOICES, null=True)
  41. class WhizIter(models.Model):
  42. c = models.IntegerField(choices=iter(Whiz.CHOICES), null=True)
  43. class WhizIterEmpty(models.Model):
  44. c = models.CharField(choices=iter(()), blank=True, max_length=1)
  45. class BigD(models.Model):
  46. d = models.DecimalField(max_digits=32, decimal_places=30)
  47. class FloatModel(models.Model):
  48. size = models.FloatField()
  49. class BigS(models.Model):
  50. s = models.SlugField(max_length=255)
  51. class UnicodeSlugField(models.Model):
  52. s = models.SlugField(max_length=255, allow_unicode=True)
  53. class SmallIntegerModel(models.Model):
  54. value = models.SmallIntegerField()
  55. class IntegerModel(models.Model):
  56. value = models.IntegerField()
  57. class BigIntegerModel(models.Model):
  58. value = models.BigIntegerField()
  59. null_value = models.BigIntegerField(null=True, blank=True)
  60. class PositiveSmallIntegerModel(models.Model):
  61. value = models.PositiveSmallIntegerField()
  62. class PositiveIntegerModel(models.Model):
  63. value = models.PositiveIntegerField()
  64. class Post(models.Model):
  65. title = models.CharField(max_length=100)
  66. body = models.TextField()
  67. class NullBooleanModel(models.Model):
  68. nbfield = models.BooleanField(null=True, blank=True)
  69. nbfield_old = models.NullBooleanField()
  70. class BooleanModel(models.Model):
  71. bfield = models.BooleanField()
  72. string = models.CharField(max_length=10, default='abc')
  73. class DateTimeModel(models.Model):
  74. d = models.DateField()
  75. dt = models.DateTimeField()
  76. t = models.TimeField()
  77. class DurationModel(models.Model):
  78. field = models.DurationField()
  79. class NullDurationModel(models.Model):
  80. field = models.DurationField(null=True)
  81. class PrimaryKeyCharModel(models.Model):
  82. string = models.CharField(max_length=10, primary_key=True)
  83. class FksToBooleans(models.Model):
  84. """Model with FKs to models with {Null,}BooleanField's, #15040"""
  85. bf = models.ForeignKey(BooleanModel, models.CASCADE)
  86. nbf = models.ForeignKey(NullBooleanModel, models.CASCADE)
  87. class FkToChar(models.Model):
  88. """Model with FK to a model with a CharField primary key, #19299"""
  89. out = models.ForeignKey(PrimaryKeyCharModel, models.CASCADE)
  90. class RenamedField(models.Model):
  91. modelname = models.IntegerField(name="fieldname", choices=((1, 'One'),))
  92. class VerboseNameField(models.Model):
  93. id = models.AutoField("verbose pk", primary_key=True)
  94. field1 = models.BigIntegerField("verbose field1")
  95. field2 = models.BooleanField("verbose field2", default=False)
  96. field3 = models.CharField("verbose field3", max_length=10)
  97. field4 = models.DateField("verbose field4")
  98. field5 = models.DateTimeField("verbose field5")
  99. field6 = models.DecimalField("verbose field6", max_digits=6, decimal_places=1)
  100. field7 = models.EmailField("verbose field7")
  101. field8 = models.FileField("verbose field8", upload_to="unused")
  102. field9 = models.FilePathField("verbose field9")
  103. field10 = models.FloatField("verbose field10")
  104. # Don't want to depend on Pillow in this test
  105. # field_image = models.ImageField("verbose field")
  106. field11 = models.IntegerField("verbose field11")
  107. field12 = models.GenericIPAddressField("verbose field12", protocol="ipv4")
  108. field13 = models.NullBooleanField("verbose field13")
  109. field14 = models.PositiveIntegerField("verbose field14")
  110. field15 = models.PositiveSmallIntegerField("verbose field15")
  111. field16 = models.SlugField("verbose field16")
  112. field17 = models.SmallIntegerField("verbose field17")
  113. field18 = models.TextField("verbose field18")
  114. field19 = models.TimeField("verbose field19")
  115. field20 = models.URLField("verbose field20")
  116. field21 = models.UUIDField("verbose field21")
  117. field22 = models.DurationField("verbose field22")
  118. class GenericIPAddress(models.Model):
  119. ip = models.GenericIPAddressField(null=True, protocol='ipv4')
  120. ###############################################################################
  121. # These models aren't used in any test, just here to ensure they validate
  122. # successfully.
  123. # See ticket #16570.
  124. class DecimalLessThanOne(models.Model):
  125. d = models.DecimalField(max_digits=3, decimal_places=3)
  126. # See ticket #18389.
  127. class FieldClassAttributeModel(models.Model):
  128. field_class = models.CharField
  129. ###############################################################################
  130. class DataModel(models.Model):
  131. short_data = models.BinaryField(max_length=10, default=b'\x08')
  132. data = models.BinaryField()
  133. ###############################################################################
  134. # FileField
  135. class Document(models.Model):
  136. myfile = models.FileField(upload_to='unused', unique=True)
  137. ###############################################################################
  138. # ImageField
  139. # If Pillow available, do these tests.
  140. if Image:
  141. class TestImageFieldFile(ImageFieldFile):
  142. """
  143. Custom Field File class that records whether or not the underlying file
  144. was opened.
  145. """
  146. def __init__(self, *args, **kwargs):
  147. self.was_opened = False
  148. super().__init__(*args, **kwargs)
  149. def open(self):
  150. self.was_opened = True
  151. super().open()
  152. class TestImageField(ImageField):
  153. attr_class = TestImageFieldFile
  154. # Set up a temp directory for file storage.
  155. temp_storage_dir = tempfile.mkdtemp()
  156. temp_storage = FileSystemStorage(temp_storage_dir)
  157. temp_upload_to_dir = os.path.join(temp_storage.location, 'tests')
  158. class Person(models.Model):
  159. """
  160. Model that defines an ImageField with no dimension fields.
  161. """
  162. name = models.CharField(max_length=50)
  163. mugshot = TestImageField(storage=temp_storage, upload_to='tests')
  164. class AbstractPersonWithHeight(models.Model):
  165. """
  166. Abstract model that defines an ImageField with only one dimension field
  167. to make sure the dimension update is correctly run on concrete subclass
  168. instance post-initialization.
  169. """
  170. mugshot = TestImageField(storage=temp_storage, upload_to='tests',
  171. height_field='mugshot_height')
  172. mugshot_height = models.PositiveSmallIntegerField()
  173. class Meta:
  174. abstract = True
  175. class PersonWithHeight(AbstractPersonWithHeight):
  176. """
  177. Concrete model that subclass an abstract one with only on dimension
  178. field.
  179. """
  180. name = models.CharField(max_length=50)
  181. class PersonWithHeightAndWidth(models.Model):
  182. """
  183. Model that defines height and width fields after the ImageField.
  184. """
  185. name = models.CharField(max_length=50)
  186. mugshot = TestImageField(storage=temp_storage, upload_to='tests',
  187. height_field='mugshot_height',
  188. width_field='mugshot_width')
  189. mugshot_height = models.PositiveSmallIntegerField()
  190. mugshot_width = models.PositiveSmallIntegerField()
  191. class PersonDimensionsFirst(models.Model):
  192. """
  193. Model that defines height and width fields before the ImageField.
  194. """
  195. name = models.CharField(max_length=50)
  196. mugshot_height = models.PositiveSmallIntegerField()
  197. mugshot_width = models.PositiveSmallIntegerField()
  198. mugshot = TestImageField(storage=temp_storage, upload_to='tests',
  199. height_field='mugshot_height',
  200. width_field='mugshot_width')
  201. class PersonTwoImages(models.Model):
  202. """
  203. Model that:
  204. * Defines two ImageFields
  205. * Defines the height/width fields before the ImageFields
  206. * Has a nullable ImageField
  207. """
  208. name = models.CharField(max_length=50)
  209. mugshot_height = models.PositiveSmallIntegerField()
  210. mugshot_width = models.PositiveSmallIntegerField()
  211. mugshot = TestImageField(storage=temp_storage, upload_to='tests',
  212. height_field='mugshot_height',
  213. width_field='mugshot_width')
  214. headshot_height = models.PositiveSmallIntegerField(
  215. blank=True, null=True)
  216. headshot_width = models.PositiveSmallIntegerField(
  217. blank=True, null=True)
  218. headshot = TestImageField(blank=True, null=True,
  219. storage=temp_storage, upload_to='tests',
  220. height_field='headshot_height',
  221. width_field='headshot_width')
  222. class AllFieldsModel(models.Model):
  223. big_integer = models.BigIntegerField()
  224. binary = models.BinaryField()
  225. boolean = models.BooleanField(default=False)
  226. char = models.CharField(max_length=10)
  227. date = models.DateField()
  228. datetime = models.DateTimeField()
  229. decimal = models.DecimalField(decimal_places=2, max_digits=2)
  230. duration = models.DurationField()
  231. email = models.EmailField()
  232. file_path = models.FilePathField()
  233. floatf = models.FloatField()
  234. integer = models.IntegerField()
  235. generic_ip = models.GenericIPAddressField()
  236. null_boolean = models.NullBooleanField()
  237. positive_integer = models.PositiveIntegerField()
  238. positive_small_integer = models.PositiveSmallIntegerField()
  239. slug = models.SlugField()
  240. small_integer = models.SmallIntegerField()
  241. text = models.TextField()
  242. time = models.TimeField()
  243. url = models.URLField()
  244. uuid = models.UUIDField()
  245. fo = ForeignObject(
  246. 'self',
  247. on_delete=models.CASCADE,
  248. from_fields=['abstract_non_concrete_id'],
  249. to_fields=['id'],
  250. related_name='reverse'
  251. )
  252. fk = ForeignKey(
  253. 'self',
  254. models.CASCADE,
  255. related_name='reverse2'
  256. )
  257. m2m = ManyToManyField('self')
  258. oto = OneToOneField('self', models.CASCADE)
  259. object_id = models.PositiveIntegerField()
  260. content_type = models.ForeignKey(ContentType, models.CASCADE)
  261. gfk = GenericForeignKey()
  262. gr = GenericRelation(DataModel)
  263. class ManyToMany(models.Model):
  264. m2m = models.ManyToManyField('self')
  265. ###############################################################################
  266. class UUIDModel(models.Model):
  267. field = models.UUIDField()
  268. class NullableUUIDModel(models.Model):
  269. field = models.UUIDField(blank=True, null=True)
  270. class PrimaryKeyUUIDModel(models.Model):
  271. id = models.UUIDField(primary_key=True, default=uuid.uuid4)
  272. class RelatedToUUIDModel(models.Model):
  273. uuid_fk = models.ForeignKey('PrimaryKeyUUIDModel', models.CASCADE)
  274. class UUIDChild(PrimaryKeyUUIDModel):
  275. pass
  276. class UUIDGrandchild(UUIDChild):
  277. pass