@@ -908,6 +908,37 @@ def with_content(self, content):
908908 return self .filter (content_ids__overlap = content_pks )
909909
910910
911+ class RepositoryVersionManager (models .Manager ):
912+ # `RepositoryVersionQuerySet.as_manager()` does not allow us to redefine `get_queryset`.
913+ # Sadly, we have to replicate the filtering amenities too.
914+ #
915+ def get_queryset (self ):
916+ # Prevent the content_ids to be automatically hydrated.
917+ return RepositoryVersionQuerySet (self .model , using = self ._db ).defer ("content_ids" )
918+
919+ def complete (self ):
920+ return self .get_queryset ().filter (complete = True )
921+
922+ def with_content (self , content ):
923+ """
924+ Filters repository versions that contain the provided content units.
925+
926+ Args:
927+ content (django.db.models.QuerySet or list): Content queryset or list of PKs
928+
929+ Returns:
930+ django.db.models.QuerySet: Repository versions which contains content.
931+ """
932+ if isinstance (content , models .QuerySet ):
933+ content_pks = content .values_list ("pk" , flat = True )
934+ elif not content :
935+ return self .none ()
936+ else :
937+ content_pks = content
938+
939+ return self .get_queryset ().filter (content_ids__overlap = content_pks )
940+
941+
911942class RepositoryVersion (BaseModel ):
912943 """
913944 A version of a repository's content set.
@@ -936,7 +967,7 @@ class RepositoryVersion(BaseModel):
936967 base_version (models.ForeignKey): The repository version this was created from.
937968 """
938969
939- objects = RepositoryVersionQuerySet . as_manager ()
970+ objects = RepositoryVersionManager ()
940971
941972 repository = models .ForeignKey (Repository , on_delete = models .CASCADE )
942973 number = models .PositiveIntegerField (db_index = True )
@@ -997,15 +1028,13 @@ def get_content(self, content_qs=None):
9971028 if content_qs is None :
9981029 content_qs = Content .objects
9991030
1000- content_ids = self .content_ids
1001- if len (content_ids ) >= 65535 :
1002- # Workaround for PostgreSQL's limit on the number of parameters in a query
1003- content_ids = (
1004- RepositoryVersion .objects .filter (pk = self .pk )
1005- .annotate (cids = Func (F ("content_ids" ), function = "unnest" ))
1006- .values_list ("cids" , flat = True )
1007- )
1008- return content_qs .filter (pk__in = content_ids )
1031+ # Try to not even attempt to evaluate the content_ids on the python side.
1032+ content_ids_subquery = (
1033+ RepositoryVersion .objects .filter (pk = self .pk )
1034+ .annotate (cids = Func (F ("content_ids" ), function = "unnest" ))
1035+ .values_list ("cids" , flat = True )
1036+ )
1037+ return content_qs .filter (pk__in = content_ids_subquery )
10091038
10101039 @property
10111040 def content (self ):
@@ -1119,9 +1148,7 @@ def added(self, base_version=None):
11191148 if not base_version :
11201149 return Content .objects .filter (version_memberships__version_added = self )
11211150
1122- return Content .objects .filter (pk__in = self .content_ids ).exclude (
1123- pk__in = base_version .content_ids
1124- )
1151+ return Content .objects .filter (pk__in = self .content ).exclude (pk__in = base_version .content )
11251152
11261153 def removed (self , base_version = None ):
11271154 """
@@ -1134,9 +1161,7 @@ def removed(self, base_version=None):
11341161 if not base_version :
11351162 return Content .objects .filter (version_memberships__version_removed = self )
11361163
1137- return Content .objects .filter (pk__in = base_version .content_ids ).exclude (
1138- pk__in = self .content_ids
1139- )
1164+ return Content .objects .filter (pk__in = base_version .content ).exclude (pk__in = self .content )
11401165
11411166 def contains (self , content ):
11421167 """
@@ -1145,7 +1170,7 @@ def contains(self, content):
11451170 Returns:
11461171 bool: True if the repository version contains the content, False otherwise
11471172 """
1148- return content .pk in self .content_ids
1173+ return content .pk in self .content
11491174
11501175 def add_content (self , content ):
11511176 """
0 commit comments