models.py 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. from django.db import models
  2. from .fields import (
  3. ArrayField,
  4. BigIntegerRangeField,
  5. DateRangeField,
  6. DateTimeRangeField,
  7. DecimalRangeField,
  8. EnumField,
  9. HStoreField,
  10. IntegerRangeField,
  11. SearchVectorField,
  12. )
  13. class Tag:
  14. def __init__(self, tag_id):
  15. self.tag_id = tag_id
  16. def __eq__(self, other):
  17. return isinstance(other, Tag) and self.tag_id == other.tag_id
  18. class TagField(models.SmallIntegerField):
  19. def from_db_value(self, value, expression, connection):
  20. if value is None:
  21. return value
  22. return Tag(int(value))
  23. def to_python(self, value):
  24. if isinstance(value, Tag):
  25. return value
  26. if value is None:
  27. return value
  28. return Tag(int(value))
  29. def get_prep_value(self, value):
  30. return value.tag_id
  31. class PostgreSQLModel(models.Model):
  32. class Meta:
  33. abstract = True
  34. required_db_vendor = "postgresql"
  35. class IntegerArrayModel(PostgreSQLModel):
  36. field = ArrayField(models.IntegerField(), default=list, blank=True)
  37. class NullableIntegerArrayModel(PostgreSQLModel):
  38. field = ArrayField(models.IntegerField(), blank=True, null=True)
  39. field_nested = ArrayField(ArrayField(models.IntegerField(null=True)), null=True)
  40. order = models.IntegerField(null=True)
  41. class CharArrayModel(PostgreSQLModel):
  42. field = ArrayField(models.CharField(max_length=10))
  43. class DateTimeArrayModel(PostgreSQLModel):
  44. datetimes = ArrayField(models.DateTimeField())
  45. dates = ArrayField(models.DateField())
  46. times = ArrayField(models.TimeField())
  47. class NestedIntegerArrayModel(PostgreSQLModel):
  48. field = ArrayField(ArrayField(models.IntegerField()))
  49. class OtherTypesArrayModel(PostgreSQLModel):
  50. ips = ArrayField(models.GenericIPAddressField(), default=list)
  51. uuids = ArrayField(models.UUIDField(), default=list)
  52. decimals = ArrayField(
  53. models.DecimalField(max_digits=5, decimal_places=2), default=list
  54. )
  55. tags = ArrayField(TagField(), blank=True, null=True)
  56. json = ArrayField(models.JSONField(default=dict), default=list)
  57. int_ranges = ArrayField(IntegerRangeField(), blank=True, null=True)
  58. bigint_ranges = ArrayField(BigIntegerRangeField(), blank=True, null=True)
  59. class HStoreModel(PostgreSQLModel):
  60. field = HStoreField(blank=True, null=True)
  61. array_field = ArrayField(HStoreField(), null=True)
  62. class ArrayEnumModel(PostgreSQLModel):
  63. array_of_enums = ArrayField(EnumField(max_length=20))
  64. class CharFieldModel(models.Model):
  65. field = models.CharField(max_length=64)
  66. class TextFieldModel(models.Model):
  67. field = models.TextField()
  68. class SmallAutoFieldModel(models.Model):
  69. id = models.SmallAutoField(primary_key=True)
  70. class BigAutoFieldModel(models.Model):
  71. id = models.BigAutoField(primary_key=True)
  72. # Scene/Character/Line models are used to test full text search. They're
  73. # populated with content from Monty Python and the Holy Grail.
  74. class Scene(models.Model):
  75. scene = models.TextField()
  76. setting = models.CharField(max_length=255)
  77. class Character(models.Model):
  78. name = models.CharField(max_length=255)
  79. class Line(PostgreSQLModel):
  80. scene = models.ForeignKey("Scene", models.CASCADE)
  81. character = models.ForeignKey("Character", models.CASCADE)
  82. dialogue = models.TextField(blank=True, null=True)
  83. dialogue_search_vector = SearchVectorField(blank=True, null=True)
  84. dialogue_config = models.CharField(max_length=100, blank=True, null=True)
  85. class LineSavedSearch(PostgreSQLModel):
  86. line = models.ForeignKey("Line", models.CASCADE)
  87. query = models.CharField(max_length=100)
  88. class RangesModel(PostgreSQLModel):
  89. ints = IntegerRangeField(blank=True, null=True)
  90. bigints = BigIntegerRangeField(blank=True, null=True)
  91. decimals = DecimalRangeField(blank=True, null=True)
  92. timestamps = DateTimeRangeField(blank=True, null=True)
  93. timestamps_inner = DateTimeRangeField(blank=True, null=True)
  94. timestamps_closed_bounds = DateTimeRangeField(
  95. blank=True,
  96. null=True,
  97. default_bounds="[]",
  98. )
  99. dates = DateRangeField(blank=True, null=True)
  100. dates_inner = DateRangeField(blank=True, null=True)
  101. class RangeLookupsModel(PostgreSQLModel):
  102. parent = models.ForeignKey(RangesModel, models.SET_NULL, blank=True, null=True)
  103. integer = models.IntegerField(blank=True, null=True)
  104. big_integer = models.BigIntegerField(blank=True, null=True)
  105. float = models.FloatField(blank=True, null=True)
  106. timestamp = models.DateTimeField(blank=True, null=True)
  107. date = models.DateField(blank=True, null=True)
  108. small_integer = models.SmallIntegerField(blank=True, null=True)
  109. decimal_field = models.DecimalField(
  110. max_digits=5, decimal_places=2, blank=True, null=True
  111. )
  112. class ArrayFieldSubclass(ArrayField):
  113. def __init__(self, *args, **kwargs):
  114. super().__init__(models.IntegerField())
  115. class AggregateTestModel(PostgreSQLModel):
  116. """
  117. To test postgres-specific general aggregation functions
  118. """
  119. char_field = models.CharField(max_length=30, blank=True)
  120. text_field = models.TextField(blank=True)
  121. integer_field = models.IntegerField(null=True)
  122. boolean_field = models.BooleanField(null=True)
  123. json_field = models.JSONField(null=True)
  124. class StatTestModel(PostgreSQLModel):
  125. """
  126. To test postgres-specific aggregation functions for statistics
  127. """
  128. int1 = models.IntegerField()
  129. int2 = models.IntegerField()
  130. related_field = models.ForeignKey(AggregateTestModel, models.SET_NULL, null=True)
  131. class NowTestModel(models.Model):
  132. when = models.DateTimeField(null=True, default=None)
  133. class UUIDTestModel(models.Model):
  134. uuid = models.UUIDField(default=None, null=True)
  135. class Room(models.Model):
  136. number = models.IntegerField(unique=True)
  137. class HotelReservation(PostgreSQLModel):
  138. room = models.ForeignKey("Room", on_delete=models.CASCADE)
  139. datespan = DateRangeField()
  140. start = models.DateTimeField()
  141. end = models.DateTimeField()
  142. cancelled = models.BooleanField(default=False)
  143. requirements = models.JSONField(blank=True, null=True)