models.py 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. import os
  2. import tempfile
  3. import uuid
  4. import warnings
  5. try:
  6. from PIL import Image
  7. except ImportError:
  8. Image = None
  9. from django.core.files.storage import FileSystemStorage
  10. from django.db import models
  11. from django.db.models.fields.files import ImageFieldFile, ImageField
  12. from django.utils import six
  13. class Foo(models.Model):
  14. a = models.CharField(max_length=10)
  15. d = models.DecimalField(max_digits=5, decimal_places=3)
  16. def get_foo():
  17. return Foo.objects.get(id=1)
  18. class Bar(models.Model):
  19. b = models.CharField(max_length=10)
  20. a = models.ForeignKey(Foo, default=get_foo, related_name=b'bars')
  21. class Whiz(models.Model):
  22. CHOICES = (
  23. ('Group 1', (
  24. (1, 'First'),
  25. (2, 'Second'),
  26. )
  27. ),
  28. ('Group 2', (
  29. (3, 'Third'),
  30. (4, 'Fourth'),
  31. )
  32. ),
  33. (0, 'Other'),
  34. )
  35. c = models.IntegerField(choices=CHOICES, null=True)
  36. class Counter(six.Iterator):
  37. def __init__(self):
  38. self.n = 1
  39. def __iter__(self):
  40. return self
  41. def __next__(self):
  42. if self.n > 5:
  43. raise StopIteration
  44. else:
  45. self.n += 1
  46. return (self.n, 'val-' + str(self.n))
  47. class WhizIter(models.Model):
  48. c = models.IntegerField(choices=Counter(), null=True)
  49. class WhizIterEmpty(models.Model):
  50. c = models.CharField(choices=(x for x in []), blank=True, max_length=1)
  51. class BigD(models.Model):
  52. d = models.DecimalField(max_digits=38, decimal_places=30)
  53. class FloatModel(models.Model):
  54. size = models.FloatField()
  55. class BigS(models.Model):
  56. s = models.SlugField(max_length=255)
  57. class SmallIntegerModel(models.Model):
  58. value = models.SmallIntegerField()
  59. class IntegerModel(models.Model):
  60. value = models.IntegerField()
  61. class BigIntegerModel(models.Model):
  62. value = models.BigIntegerField()
  63. null_value = models.BigIntegerField(null=True, blank=True)
  64. class PositiveSmallIntegerModel(models.Model):
  65. value = models.PositiveSmallIntegerField()
  66. class PositiveIntegerModel(models.Model):
  67. value = models.PositiveIntegerField()
  68. class Post(models.Model):
  69. title = models.CharField(max_length=100)
  70. body = models.TextField()
  71. class NullBooleanModel(models.Model):
  72. nbfield = models.NullBooleanField()
  73. class BooleanModel(models.Model):
  74. bfield = models.BooleanField(default=None)
  75. string = models.CharField(max_length=10, default='abc')
  76. class DateTimeModel(models.Model):
  77. d = models.DateField()
  78. dt = models.DateTimeField()
  79. t = models.TimeField()
  80. class DurationModel(models.Model):
  81. field = models.DurationField()
  82. class PrimaryKeyCharModel(models.Model):
  83. string = models.CharField(max_length=10, primary_key=True)
  84. class FksToBooleans(models.Model):
  85. """Model with FKs to models with {Null,}BooleanField's, #15040"""
  86. bf = models.ForeignKey(BooleanModel)
  87. nbf = models.ForeignKey(NullBooleanModel)
  88. class FkToChar(models.Model):
  89. """Model with FK to a model with a CharField primary key, #19299"""
  90. out = models.ForeignKey(PrimaryKeyCharModel)
  91. class RenamedField(models.Model):
  92. modelname = models.IntegerField(name="fieldname", choices=((1, 'One'),))
  93. class VerboseNameField(models.Model):
  94. id = models.AutoField("verbose pk", primary_key=True)
  95. field1 = models.BigIntegerField("verbose field1")
  96. field2 = models.BooleanField("verbose field2", default=False)
  97. field3 = models.CharField("verbose field3", max_length=10)
  98. field4 = models.CommaSeparatedIntegerField("verbose field4", max_length=99)
  99. field5 = models.DateField("verbose field5")
  100. field6 = models.DateTimeField("verbose field6")
  101. field7 = models.DecimalField("verbose field7", max_digits=6, decimal_places=1)
  102. field8 = models.EmailField("verbose field8")
  103. field9 = models.FileField("verbose field9", upload_to="unused")
  104. field10 = models.FilePathField("verbose field10")
  105. field11 = models.FloatField("verbose field11")
  106. # Don't want to depend on Pillow in this test
  107. #field_image = models.ImageField("verbose field")
  108. field12 = models.IntegerField("verbose field12")
  109. with warnings.catch_warnings(record=True) as w:
  110. warnings.simplefilter("always")
  111. field13 = models.IPAddressField("verbose field13")
  112. field14 = models.GenericIPAddressField("verbose field14", protocol="ipv4")
  113. field15 = models.NullBooleanField("verbose field15")
  114. field16 = models.PositiveIntegerField("verbose field16")
  115. field17 = models.PositiveSmallIntegerField("verbose field17")
  116. field18 = models.SlugField("verbose field18")
  117. field19 = models.SmallIntegerField("verbose field19")
  118. field20 = models.TextField("verbose field20")
  119. field21 = models.TimeField("verbose field21")
  120. field22 = models.URLField("verbose field22")
  121. ###############################################################################
  122. # These models aren't used in any test, just here to ensure they validate
  123. # successfully.
  124. # See ticket #16570.
  125. class DecimalLessThanOne(models.Model):
  126. d = models.DecimalField(max_digits=3, decimal_places=3)
  127. # See ticket #18389.
  128. class FieldClassAttributeModel(models.Model):
  129. field_class = models.CharField
  130. ###############################################################################
  131. class DataModel(models.Model):
  132. short_data = models.BinaryField(max_length=10, default=b'\x08')
  133. data = models.BinaryField()
  134. ###############################################################################
  135. # FileField
  136. class Document(models.Model):
  137. myfile = models.FileField(upload_to='unused')
  138. ###############################################################################
  139. # ImageField
  140. # If Pillow available, do these tests.
  141. if Image:
  142. class TestImageFieldFile(ImageFieldFile):
  143. """
  144. Custom Field File class that records whether or not the underlying file
  145. was opened.
  146. """
  147. def __init__(self, *args, **kwargs):
  148. self.was_opened = False
  149. super(TestImageFieldFile, self).__init__(*args, **kwargs)
  150. def open(self):
  151. self.was_opened = True
  152. super(TestImageFieldFile, self).open()
  153. class TestImageField(ImageField):
  154. attr_class = TestImageFieldFile
  155. # Set up a temp directory for file storage.
  156. temp_storage_dir = tempfile.mkdtemp(dir=os.environ['DJANGO_TEST_TEMP_DIR'])
  157. temp_storage = FileSystemStorage(temp_storage_dir)
  158. temp_upload_to_dir = os.path.join(temp_storage.location, 'tests')
  159. class Person(models.Model):
  160. """
  161. Model that defines an ImageField with no dimension fields.
  162. """
  163. name = models.CharField(max_length=50)
  164. mugshot = TestImageField(storage=temp_storage, upload_to='tests')
  165. class AbsctractPersonWithHeight(models.Model):
  166. """
  167. Abstract model that defines an ImageField with only one dimension field
  168. to make sure the dimension update is correctly run on concrete subclass
  169. instance post-initialization.
  170. """
  171. mugshot = TestImageField(storage=temp_storage, upload_to='tests',
  172. height_field='mugshot_height')
  173. mugshot_height = models.PositiveSmallIntegerField()
  174. class Meta:
  175. abstract = True
  176. class PersonWithHeight(AbsctractPersonWithHeight):
  177. """
  178. Concrete model that subclass an abctract one with only on dimension
  179. field.
  180. """
  181. name = models.CharField(max_length=50)
  182. class PersonWithHeightAndWidth(models.Model):
  183. """
  184. Model that defines height and width fields after the ImageField.
  185. """
  186. name = models.CharField(max_length=50)
  187. mugshot = TestImageField(storage=temp_storage, upload_to='tests',
  188. height_field='mugshot_height',
  189. width_field='mugshot_width')
  190. mugshot_height = models.PositiveSmallIntegerField()
  191. mugshot_width = models.PositiveSmallIntegerField()
  192. class PersonDimensionsFirst(models.Model):
  193. """
  194. Model that defines height and width fields before the ImageField.
  195. """
  196. name = models.CharField(max_length=50)
  197. mugshot_height = models.PositiveSmallIntegerField()
  198. mugshot_width = models.PositiveSmallIntegerField()
  199. mugshot = TestImageField(storage=temp_storage, upload_to='tests',
  200. height_field='mugshot_height',
  201. width_field='mugshot_width')
  202. class PersonTwoImages(models.Model):
  203. """
  204. Model that:
  205. * Defines two ImageFields
  206. * Defines the height/width fields before the ImageFields
  207. * Has a nullalble ImageField
  208. """
  209. name = models.CharField(max_length=50)
  210. mugshot_height = models.PositiveSmallIntegerField()
  211. mugshot_width = models.PositiveSmallIntegerField()
  212. mugshot = TestImageField(storage=temp_storage, upload_to='tests',
  213. height_field='mugshot_height',
  214. width_field='mugshot_width')
  215. headshot_height = models.PositiveSmallIntegerField(
  216. blank=True, null=True)
  217. headshot_width = models.PositiveSmallIntegerField(
  218. blank=True, null=True)
  219. headshot = TestImageField(blank=True, null=True,
  220. storage=temp_storage, upload_to='tests',
  221. height_field='headshot_height',
  222. width_field='headshot_width')
  223. ###############################################################################
  224. class UUIDModel(models.Model):
  225. field = models.UUIDField()
  226. class NullableUUIDModel(models.Model):
  227. field = models.UUIDField(blank=True, null=True)
  228. class PrimaryKeyUUIDModel(models.Model):
  229. id = models.UUIDField(primary_key=True, default=uuid.uuid4)