Skip to content
This repository has been archived by the owner on Jun 27, 2024. It is now read-only.

Commit

Permalink
docs(manager): Add docstrings to select areas #57
Browse files Browse the repository at this point in the history
Added some docstrings to some classes to help understand how it all
works, they are available when you hover so its easy to see what its doing.

closes #57
  • Loading branch information
imAsparky committed May 5, 2023
1 parent 222f1b6 commit d524d44
Show file tree
Hide file tree
Showing 2 changed files with 144 additions and 5 deletions.
138 changes: 134 additions & 4 deletions tag_fields/managers.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,25 @@ def __init__(self, alias, col, content_types):
self.content_types = content_types

def as_sql(self, compiler, connection):
"""
Returns content_types and a string/list of Join Restrictions.
Paramaters
==========
:param compiler: A bandle to :class:`django.db.models.sql.compiler.SQLCompiler` # noqa: E501
:type compiler: class:`django.db.models.sql.compiler.SQLCompiler`
:param connection: todo
:type connection: todo
:return: String is in the format `'alias.col = %s'` for one
content_type or 'alias.col IN (%s%s%s)' for multiple content types.
:rtype: str
:return content_types: A string or list of content types
:rtype: str or [str,str, ...]
"""
qn = compiler.quote_name_unless_alias
if len(self.content_types) == 1:
extra_where = f"{qn(self.alias)}.{qn(self.col)} = %s"
Expand All @@ -61,8 +80,34 @@ def clone(self):


class _TaggableManager(models.Manager):
# TODO investigate whether we can use a RelatedManager instead of all this
# stuff to take advantage of all the Django goodness
"""
Base class for Taggable Manager.
Paramaters
==========
:param through: The name of the django through table
:type through: str
:param model: The namen of the model for the Taggable manager
:type model: str
:param instance: Instance for the Taggable manager
:type instance: class:`models.Model`
:param prefetch_cache_name: todo
:type prefetch_cache_name: todo
:param ordering: todo
:type ordering: todo
.. todo::
Very old todo here.
Investigate whether we can use a RelatedManager instead of all this
stuff to take advantage of all the Django goodness
"""

def __init__(
self,
through,
Expand Down Expand Up @@ -96,6 +141,21 @@ def get_queryset(self, extra_filters=None):
).order_by(*self.ordering)

def get_prefetch_queryset(self, instances, queryset=None):
"""
Overrides get_prefetch_queryset.
Paramaters
==========
:param instance: Instance for Self
:type instance: class:`models.Model`
:param queryset: A django queryset, Should be None and will raise an
error if supplied.
:type queryset: todo
:raises ValueError: Custom queryset can't be used for this lookup.
"""
if queryset is not None:
raise ValueError("Custom queryset can't be used for this lookup.")

Expand Down Expand Up @@ -164,6 +224,30 @@ def _remove_prefetched_objects(self):

@require_instance_manager
def add(self, *tags, through_defaults=None, tag_kwargs=None, **kwargs):
"""
Add tags to an object using either ``Tag`` instances or strings.
Paramaters
==========
:param tags: A list of tags to get or create.
:type tags: List [str,str,str ...]
:param through_defaults: You can specify values for your custom through
model by providing an argument if necessary.
:param tag_kwargs: TDefault: None his enables users to set specific
parameters for the tags.
:type tag_kwargs: dict, optional
.. todo::
Check if hardcode 'tag_id' in ``vals`` or should the column name be
got dynamically from somewhere?
Old todo, see vals below.
"""

self._remove_prefetched_objects()
if tag_kwargs is None:
tag_kwargs = {}
Expand Down Expand Up @@ -441,6 +525,40 @@ def similar_objects(self):


class TaggableManager(RelatedField):
"""
Manager for handling the actions required on Tags.
Paramaters
==========
:param blank: Default: False Determines if the field is required
:type blank: bool, optional
:param help_text: Default: _("A comma-separated list of tags.") The help
text that should be used in forms, including the admin.
:type help_text: str, optional
:param manager: Default: :class:`managers._TaggableManager` The Taggable
manager to use for this instance.
:type manager:
:param ordering: Default: None
:type ordering: todo, optional
:param related_name:
:type related_name: str, optional
:param through: Default: None The through table model, see
:doc:`custom_tagging` for more information.
:type through: str, optional
:param to: Default: None
:type to: todo, optional
:param verbose_name: Default: _("Tags") This field's verbose name.
:type verbose_name: str, optional
"""

# Field flags
many_to_many = True
many_to_one = False
Expand Down Expand Up @@ -480,6 +598,16 @@ def __init__(
self.manager = manager

def __get__(self, instance, model):
"""
Check the instance has a primary key.
:raises ValueError: "%s objects need to have a primary key value "
"before you can access their tags." % model.__name__
:return: An instance of the default manager.
:rtype: :class:`managers._TaggableManager`
"""

if instance is not None and instance.pk is None:
raise ValueError(
"%s objects need to have a primary key value "
Expand Down Expand Up @@ -732,7 +860,8 @@ def reverse_path_infos(self):

def get_joining_columns(self, reverse_join=False):
# RemovedInDjango60Warning
# https://github.com/django/django/commit/8b1ff0da4b162e87edebd94e61f2cd153e9e159d
# https://github.com/django/django/commit/8b1ff0da4b162e87edebd94e61f2cd153e9e159d # noqa: E501
# Use "get_joining_fields() instead."
if reverse_join:
return ((self.model._meta.pk.column, "object_id"),)
else:
Expand Down Expand Up @@ -776,7 +905,8 @@ def _get_extra_restriction_legacy(self, where_class, alias, related_alias):

def get_reverse_joining_columns(self):
# RemovedInDjango60Warning
# https://github.com/django/django/commit/8b1ff0da4b162e87edebd94e61f2cd153e9e159d
# https://github.com/django/django/commit/8b1ff0da4b162e87edebd94e61f2cd153e9e159d # noqa: E501
# Use "get_reverse_joining_fields() instead."
return self.get_joining_columns(reverse_join=True)

def get_reverse_joining_fields(self):
Expand Down
11 changes: 10 additions & 1 deletion tag_fields/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,10 +117,19 @@ def _edit_string_for_tags(tags):


def require_instance_manager(func):
"""
Checks the instance exists.
:raises TypeError: "Can't call %s with a non-instance manager" % func.__name__ # noqa: E501
"""

@wraps(func)
def inner(self, *args, **kwargs):
if self.instance is None:
raise TypeError("Can't call %s with a non-instance manager" % func.__name__)
raise TypeError(
"Can't call %s with a non-instance manager" % func.__name__
)
return func(self, *args, **kwargs)

return inner
Expand Down

0 comments on commit d524d44

Please sign in to comment.