Nathan Maier
Nathan Maier

Reputation: 1

Using Mezzanine (Django) and updating to django 5.0 : I get "TypeError: QuerySet._clone() got an unexpected keyword argument '_search_terms'"

I'm installing mezzanine vie netbsd packages because I found that's the easiest for netbsd.
I'm stuck on the following error message. I've found great answers for every other upgraded code like modules that have changed. I am consulting the django docs, but I thought I'd start by asking in this forum how to change the code to give the right search terms. I assume that changinge mezzanine/core/managers.py is the way to go.

I've used mezzanine for a long time and hope that it gains new life. An anecdote: I got hired to manage an electric assist cargo bike company for a home valet compost service and I found that the management used mezzanine(django) for their website. When I asked about contributing to the website, the young snobs snubbed me without giving me a chance. but anyway:

    Traceback (most recent call last):
 `enter code here` File "/home/nate/cleanair/manage.py", line 14, in <m`enter code here`odule>
  `enter code here`  execute_from_command_line(sys.argv)
  ``File "/usr/pkg/lib/python3.11/site-packages/django/core/management/__init__.py", line 419, in execute_from_command_line
    utility.execute()
  File "/usr/pkg/lib/python3.11/site-packages/django/core/management/__init__.py", line 395, in execute
    django.setup()
  File "/usr/pkg/lib/python3.11/site-packages/django/__init__.py", line 24, in setup
    apps.populate(settings.INSTALLED_APPS)
  File "/usr/pkg/lib/python3.11/site-packages/django/apps/registry.py", line 122, in populate
    app_config.ready()
  File "/usr/pkg/lib/python3.11/site-packages/django/contrib/admin/apps.py", line 27, in ready
    self.module.autodiscover()
  File "/usr/pkg/lib/python3.11/site-packages/mezzanine/boot/__init__.py", line 114, in autodiscover
    django_autodiscover(*args, **kwargs)
  File "/usr/pkg/lib/python3.11/site-packages/django/contrib/admin/__init__.py", line 24, in autodiscover
    autodiscover_modules('admin', register_to=site)
  File "/usr/pkg/lib/python3.11/site-packages/django/utils/module_loading.py", line 47, in autodiscover_modules
    import_module('%s.%s' % (app_config.name, module_to_search))
  File "/usr/pkg/lib/python3.11/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<frozen importlib._bootstrap>", line 1204, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1147, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 940, in exec_module
  File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
  File "/usr/pkg/lib/python3.11/site-packages/mezzanine/forms/admin.py", line 43, in <module>
    class FieldAdminInlineForm(DynamicInlineAdminForm):
  File "/usr/pkg/lib/python3.11/site-packages/django/forms/models.py", line 261, in __new__
    fields = fields_for_model(
             ^^^^^^^^^^^^^^^^^
  File "/usr/pkg/lib/python3.11/site-packages/django/forms/models.py", line 183, in fields_for_model
    formfield = f.formfield(**kwargs)
                ^^^^^^^^^^^^^^^^^^^^^
  File "/usr/pkg/lib/python3.11/site-packages/django/db/models/fields/related.py", line 991, in formfield
    'queryset': self.remote_field.model._default_manager.using(using),
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/pkg/lib/python3.11/site-packages/django/db/models/manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
                   ^^^^^^^^^^^^^^^^^^^
  File "/usr/pkg/lib/python3.11/site-packages/mezzanine/core/managers.py", line 386, in get_queryset
    return super(DjangoCSM, self).get_queryset().filter(**lookup)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/pkg/lib/python3.11/site-packages/django/db/models/query.py", line 941, in filter
    return self._filter_or_exclude(False, args, kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/pkg/lib/python3.11/site-packages/django/db/models/query.py", line 956, in _filter_or_exclude
    clone = self._chain()
            ^^^^^^^^^^^^^
  File "/usr/pkg/lib/python3.11/site-packages/django/db/models/query.py", line 1301, in _chain
    obj = self._clone()
          ^^^^^^^^^^^^^
  File "/usr/pkg/lib/python3.11/site-packages/mezzanine/core/managers.py", line 180, in _clone
    return super(SearchableQuerySet, self)._clone(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: QuerySet._clone() got an unexpected keyword argument '_search_terms'

'''

I haven't tried anything here other than researching the source code. I will keep exploring it.

and what I think are the relative pieces of code in the mezzanine/core/mangaers.py

class SearchableQuerySet(QuerySet):
"""
QuerySet providing main search functionality for
``SearchableManager``.
"""

def __init__(self, *args, **kwargs):
    self._search_ordered = False
    self._search_terms = set()
    self._search_fields = kwargs.pop("search_fields", {})
    super(SearchableQuerySet, self).__init__(*args, **kwargs)

def search(self, query, search_fields=None):
    """
    Build a queryset matching words in the given search query,
    treating quoted terms as exact phrases and taking into
    account + and - symbols as modifiers controlling which terms
    to require and exclude.
    """

    # ### DETERMINE FIELDS TO SEARCH ###

    # Use search_fields arg if given, otherwise use search_fields
    # initially configured by the manager class.
    if search_fields:
        self._search_fields = search_fields_to_dict(search_fields)
    if not self._search_fields:
        return self.none()

    # ### BUILD LIST OF TERMS TO SEARCH FOR ###

    # Remove extra spaces, put modifiers inside quoted terms.
    terms = " ".join(query.split()).replace("+ ", "+")     \
                                   .replace('+"', '"+')    \
                                   .replace("- ", "-")     \
                                   .replace('-"', '"-')    \
                                   .split('"')
    # Strip punctuation other than modifiers from terms and create
    # terms list, first from quoted terms and then remaining words.
    terms = [("" if t[0:1] not in "+-" else t[0:1]) + t.strip(punctuation)
        for t in terms[1::2] + "".join(terms[::2]).split()]
    # Remove stop words from terms that aren't quoted or use
    # modifiers, since words with these are an explicit part of
    # the search query. If doing so ends up with an empty term
    # list, then keep the stop words.
    terms_no_stopwords = [t for t in terms if t.lower() not in
        settings.STOP_WORDS]
    get_positive_terms = lambda terms: [t.lower().strip(punctuation)
        for t in terms if t[0:1] != "-"]
    positive_terms = get_positive_terms(terms_no_stopwords)
    if positive_terms:
        terms = terms_no_stopwords
    else:
        positive_terms = get_positive_terms(terms)
    # Append positive terms (those without the negative modifier)
    # to the internal list for sorting when results are iterated.
    if not positive_terms:
        return self.none()
    else:
        self._search_terms.update(positive_terms)

    # ### BUILD QUERYSET FILTER ###

    # Create the queryset combining each set of terms.
    excluded = [reduce(iand, [~Q(**{"%s__icontains" % f: t[1:]}) for f in
        self._search_fields.keys()]) for t in terms if t[0:1] == "-"]
    required = [reduce(ior, [Q(**{"%s__icontains" % f: t[1:]}) for f in
        self._search_fields.keys()]) for t in terms if t[0:1] == "+"]
    optional = [reduce(ior, [Q(**{"%s__icontains" % f: t}) for f in
        self._search_fields.keys()]) for t in terms if t[0:1] not in "+-"]
    queryset = self
    if excluded:
        queryset = queryset.filter(reduce(iand, excluded))
    if required:
        queryset = queryset.filter(reduce(iand, required))
    # Optional terms aren't relevant to the filter if there are
    # terms that are explicitly required.
    elif optional:
        queryset = queryset.filter(reduce(ior, optional))
    return queryset.distinct()

def _clone(self, *args, **kwargs):
    """
    Ensure attributes are copied to subsequent queries.
    """
    for attr in ("_search_terms", "_search_fields", "_search_ordered"):
        kwargs[attr] = getattr(self, attr)
    return super(SearchableQuerySet, self)._clone(*args, **kwargs)

def order_by(self, *field_names):
    """
    Mark the filter as being ordered if search has occurred.
    """
    if not self._search_ordered:
        self._search_ordered = len(self._search_terms) > 0
    return super(SearchableQuerySet, self).order_by(*field_names)

def annotate_scores(self):
    """
    If search has occurred and no ordering has occurred, decorate
    each result with the number of search terms so that it can be
    sorted by the number of occurrence of terms.

    In the case of search fields that span model relationships, we
    cannot accurately match occurrences without some very
    complicated traversal code, which we won't attempt. So in this
    case, namely when there are no matches for a result (count=0),
    and search fields contain relationships (double underscores),
    we assume one match for one of the fields, and use the average
    weight of all search fields with relationships.
    """
    results = super(SearchableQuerySet, self).iterator()
    if self._search_terms and not self._search_ordered:
        results = list(results)
        for i, result in enumerate(results):
            count = 0
            related_weights = []
            for (field, weight) in self._search_fields.items():
                if "__" in field:
                    related_weights.append(weight)
                for term in self._search_terms:
                    field_value = getattr(result, field, None)
                    if field_value:
                        count += field_value.lower().count(term) * weight
            if not count and related_weights:
                count = int(sum(related_weights) / len(related_weights))

            if result.publish_date:
                age = (now() - result.publish_date).total_seconds()
                if age > 0:
                    count = count / age**settings.SEARCH_AGE_SCALE_FACTOR

            results[i].result_count = count
        return iter(results)
    return results

'''

Upvotes: 0

Views: 83

Answers (0)

Related Questions