models.py 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. from django.core.serializers.json import DjangoJSONEncoder
  2. from django.db import models
  3. from .fields import (
  4. ArrayField, BigIntegerRangeField, CICharField, CIEmailField, CITextField,
  5. DateRangeField, DateTimeRangeField, FloatRangeField, HStoreField,
  6. IntegerRangeField, JSONField, SearchVectorField,
  7. )
  8. class Tag:
  9. def __init__(self, tag_id):
  10. self.tag_id = tag_id
  11. def __eq__(self, other):
  12. return isinstance(other, Tag) and self.tag_id == other.tag_id
  13. class TagField(models.SmallIntegerField):
  14. def from_db_value(self, value, expression, connection):
  15. if value is None:
  16. return value
  17. return Tag(int(value))
  18. def to_python(self, value):
  19. if isinstance(value, Tag):
  20. return value
  21. if value is None:
  22. return value
  23. return Tag(int(value))
  24. def get_prep_value(self, value):
  25. return value.tag_id
  26. class PostgreSQLModel(models.Model):
  27. class Meta:
  28. abstract = True
  29. required_db_vendor = 'postgresql'
  30. class IntegerArrayModel(PostgreSQLModel):
  31. field = ArrayField(models.IntegerField(), default=[], blank=True)
  32. class NullableIntegerArrayModel(PostgreSQLModel):
  33. field = ArrayField(models.IntegerField(), blank=True, null=True)
  34. class CharArrayModel(PostgreSQLModel):
  35. field = ArrayField(models.CharField(max_length=10))
  36. class DateTimeArrayModel(PostgreSQLModel):
  37. datetimes = ArrayField(models.DateTimeField())
  38. dates = ArrayField(models.DateField())
  39. times = ArrayField(models.TimeField())
  40. class NestedIntegerArrayModel(PostgreSQLModel):
  41. field = ArrayField(ArrayField(models.IntegerField()))
  42. class OtherTypesArrayModel(PostgreSQLModel):
  43. ips = ArrayField(models.GenericIPAddressField())
  44. uuids = ArrayField(models.UUIDField())
  45. decimals = ArrayField(models.DecimalField(max_digits=5, decimal_places=2))
  46. tags = ArrayField(TagField(), blank=True, null=True)
  47. class HStoreModel(PostgreSQLModel):
  48. field = HStoreField(blank=True, null=True)
  49. array_field = ArrayField(HStoreField(), null=True)
  50. class CharFieldModel(models.Model):
  51. field = models.CharField(max_length=16)
  52. class TextFieldModel(models.Model):
  53. field = models.TextField()
  54. def __str__(self):
  55. return self.field
  56. # Scene/Character/Line models are used to test full text search. They're
  57. # populated with content from Monty Python and the Holy Grail.
  58. class Scene(models.Model):
  59. scene = models.CharField(max_length=255)
  60. setting = models.CharField(max_length=255)
  61. def __str__(self):
  62. return self.scene
  63. class Character(models.Model):
  64. name = models.CharField(max_length=255)
  65. def __str__(self):
  66. return self.name
  67. class CITestModel(PostgreSQLModel):
  68. name = CICharField(primary_key=True, max_length=255)
  69. email = CIEmailField()
  70. description = CITextField()
  71. array_field = ArrayField(CITextField(), null=True)
  72. def __str__(self):
  73. return self.name
  74. class Line(PostgreSQLModel):
  75. scene = models.ForeignKey('Scene', models.CASCADE)
  76. character = models.ForeignKey('Character', models.CASCADE)
  77. dialogue = models.TextField(blank=True, null=True)
  78. dialogue_search_vector = SearchVectorField(blank=True, null=True)
  79. dialogue_config = models.CharField(max_length=100, blank=True, null=True)
  80. def __str__(self):
  81. return self.dialogue or ''
  82. class RangesModel(PostgreSQLModel):
  83. ints = IntegerRangeField(blank=True, null=True)
  84. bigints = BigIntegerRangeField(blank=True, null=True)
  85. floats = FloatRangeField(blank=True, null=True)
  86. timestamps = DateTimeRangeField(blank=True, null=True)
  87. dates = DateRangeField(blank=True, null=True)
  88. class RangeLookupsModel(PostgreSQLModel):
  89. parent = models.ForeignKey(RangesModel, models.SET_NULL, blank=True, null=True)
  90. integer = models.IntegerField(blank=True, null=True)
  91. big_integer = models.BigIntegerField(blank=True, null=True)
  92. float = models.FloatField(blank=True, null=True)
  93. timestamp = models.DateTimeField(blank=True, null=True)
  94. date = models.DateField(blank=True, null=True)
  95. class JSONModel(models.Model):
  96. field = JSONField(blank=True, null=True)
  97. field_custom = JSONField(blank=True, null=True, encoder=DjangoJSONEncoder)
  98. class Meta:
  99. required_db_features = ['has_jsonb_datatype']
  100. class ArrayFieldSubclass(ArrayField):
  101. def __init__(self, *args, **kwargs):
  102. super().__init__(models.IntegerField())
  103. class AggregateTestModel(models.Model):
  104. """
  105. To test postgres-specific general aggregation functions
  106. """
  107. char_field = models.CharField(max_length=30, blank=True)
  108. integer_field = models.IntegerField(null=True)
  109. boolean_field = models.NullBooleanField()
  110. class StatTestModel(models.Model):
  111. """
  112. To test postgres-specific aggregation functions for statistics
  113. """
  114. int1 = models.IntegerField()
  115. int2 = models.IntegerField()
  116. related_field = models.ForeignKey(AggregateTestModel, models.SET_NULL, null=True)
  117. class NowTestModel(models.Model):
  118. when = models.DateTimeField(null=True, default=None)
  119. class UUIDTestModel(models.Model):
  120. uuid = models.UUIDField(default=None, null=True)