Collection: also save the collection UID on the model itself.

This enables us to have db-constraints for making sure that UIDs are
unique, as well as being more efficient for lookups (which are very
common).

The UID should always be the same as the main_item.uid, though that's
easily enforced as neither of them is allowed to change.
This commit is contained in:
Tom Hacohen
2020-12-14 13:30:30 +02:00
parent 057b908565
commit baa42d040d
7 changed files with 93 additions and 30 deletions

View File

@@ -43,6 +43,8 @@ class CollectionType(models.Model):
class Collection(models.Model):
main_item = models.OneToOneField("CollectionItem", related_name="parent", null=True, on_delete=models.SET_NULL)
# The same as main_item.uid, we just also save it here so we have DB constraints for uniqueness (and efficiency)
uid = models.CharField(db_index=True, unique=True, blank=False, max_length=43, validators=[UidValidator])
owner = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
stoken_annotation = stoken_annotation_builder(["items__revisions__stoken", "members__stoken"])
@@ -50,10 +52,6 @@ class Collection(models.Model):
def __str__(self):
return self.uid
@cached_property
def uid(self):
return self.main_item.uid
@property
def content(self):
return self.main_item.content
@@ -76,20 +74,6 @@ class Collection(models.Model):
return Stoken.objects.get(id=stoken_id).uid
def validate_unique(self, exclude=None):
super().validate_unique(exclude=exclude)
if exclude is None or "main_item" in exclude:
return
if (
self.__class__.objects.filter(owner=self.owner, main_item__uid=self.main_item.uid)
.exclude(id=self.id)
.exists()
):
raise EtebaseValidationError(
"unique_uid", "Collection with this uid already exists", status_code=status.HTTP_409_CONFLICT
)
class CollectionItem(models.Model):
uid = models.CharField(db_index=True, blank=False, max_length=43, validators=[UidValidator])