models.py 5.3 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, DecimalRangeField, 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=list, 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(), default=list)
  44. uuids = ArrayField(models.UUIDField(), default=list)
  45. decimals = ArrayField(models.DecimalField(max_digits=5, decimal_places=2), default=list)
  46. tags = ArrayField(TagField(), blank=True, null=True)
  47. json = ArrayField(JSONField(default=dict), default=list)
  48. int_ranges = ArrayField(IntegerRangeField(), blank=True, null=True)
  49. bigint_ranges = ArrayField(BigIntegerRangeField(), blank=True, null=True)
  50. class HStoreModel(PostgreSQLModel):
  51. field = HStoreField(blank=True, null=True)
  52. array_field = ArrayField(HStoreField(), null=True)
  53. class CharFieldModel(models.Model):
  54. field = models.CharField(max_length=16)
  55. class TextFieldModel(models.Model):
  56. field = models.TextField()
  57. def __str__(self):
  58. return self.field
  59. # Scene/Character/Line models are used to test full text search. They're
  60. # populated with content from Monty Python and the Holy Grail.
  61. class Scene(models.Model):
  62. scene = models.CharField(max_length=255)
  63. setting = models.CharField(max_length=255)
  64. def __str__(self):
  65. return self.scene
  66. class Character(models.Model):
  67. name = models.CharField(max_length=255)
  68. def __str__(self):
  69. return self.name
  70. class CITestModel(PostgreSQLModel):
  71. name = CICharField(primary_key=True, max_length=255)
  72. email = CIEmailField()
  73. description = CITextField()
  74. array_field = ArrayField(CITextField(), null=True)
  75. def __str__(self):
  76. return self.name
  77. class Line(PostgreSQLModel):
  78. scene = models.ForeignKey('Scene', models.CASCADE)
  79. character = models.ForeignKey('Character', models.CASCADE)
  80. dialogue = models.TextField(blank=True, null=True)
  81. dialogue_search_vector = SearchVectorField(blank=True, null=True)
  82. dialogue_config = models.CharField(max_length=100, blank=True, null=True)
  83. def __str__(self):
  84. return self.dialogue or ''
  85. class RangesModel(PostgreSQLModel):
  86. ints = IntegerRangeField(blank=True, null=True)
  87. bigints = BigIntegerRangeField(blank=True, null=True)
  88. decimals = DecimalRangeField(blank=True, null=True)
  89. timestamps = DateTimeRangeField(blank=True, null=True)
  90. dates = DateRangeField(blank=True, null=True)
  91. class RangeLookupsModel(PostgreSQLModel):
  92. parent = models.ForeignKey(RangesModel, models.SET_NULL, blank=True, null=True)
  93. integer = models.IntegerField(blank=True, null=True)
  94. big_integer = models.BigIntegerField(blank=True, null=True)
  95. float = models.FloatField(blank=True, null=True)
  96. timestamp = models.DateTimeField(blank=True, null=True)
  97. date = models.DateField(blank=True, null=True)
  98. class JSONModel(PostgreSQLModel):
  99. field = JSONField(blank=True, null=True)
  100. field_custom = JSONField(blank=True, null=True, encoder=DjangoJSONEncoder)
  101. class ArrayFieldSubclass(ArrayField):
  102. def __init__(self, *args, **kwargs):
  103. super().__init__(models.IntegerField())
  104. class AggregateTestModel(models.Model):
  105. """
  106. To test postgres-specific general aggregation functions
  107. """
  108. char_field = models.CharField(max_length=30, blank=True)
  109. integer_field = models.IntegerField(null=True)
  110. boolean_field = models.BooleanField(null=True)
  111. class StatTestModel(models.Model):
  112. """
  113. To test postgres-specific aggregation functions for statistics
  114. """
  115. int1 = models.IntegerField()
  116. int2 = models.IntegerField()
  117. related_field = models.ForeignKey(AggregateTestModel, models.SET_NULL, null=True)
  118. class NowTestModel(models.Model):
  119. when = models.DateTimeField(null=True, default=None)
  120. class UUIDTestModel(models.Model):
  121. uuid = models.UUIDField(default=None, null=True)