0

I have seen many such errors but none of them matched what i am searching so kindly help me to understand where am i making mistake in saving signals in django. I know that save method is running infinity time but how do i stop in my code as I am beginner not able to understand what or where exactly i should be making changes.

from django.db import models
import random
import os
from .utils import unique_slug_generator
from django.db.models.signals import pre_save, post_save

class ProductQuerySet(models.query.QuerySet):    
    def active(self):
        return self.filter(active=True)

    def featured(self):
        return self.filter(featured=True, active=True)

class ProductManager(models.Manager):
    def get_queryset(self):
        return ProductQuerySet(self.model, using=self._db)

    def all(self):
        return self.get_queryset().active()

    def features(self):
        return self.get_queryset().featured()

    def get_by_id(self, id):
        qs=self.get_queryset().filter(id=id)
        if qs.count() ==1:
            return qs.first()
        return None

# Create your models here.
class Product(models.Model):
    title = models.CharField(max_length=120)
    slug = models.SlugField(blank=True, unique=True)
    description = models.TextField()
    price = models.DecimalField(decimal_places=2, max_digits=20, default=39.99)
    image = models.ImageField(upload_to='products/', null=True, blank=True)
    featured = models.BooleanField(default=False)
    active = models.BooleanField(default=True)    

    objects=ProductManager()

    def __str__(self):
        return self.title

    def __unicode__(self):
        return self.title

def product_pre_save_receiver(sender, instance, *args, **kwargs):
    if not instance.slug:
        instance.slug = unique_slug_generator(instance)

pre_save.connect(product_pre_save_receiver, sender=Product)

This is may model.py

from django.utils.text import slugify

import random
import string

def random_string_generator(size=10, chars=string.ascii_lowercase+string.digits):
    return ''.join(random.choice(chars) for _ in range(size))

def unique_slug_generator(instance, new_slug=None):
    if new_slug is not None:
        slug = new_slug
    else:
        slug = slugify(instance.title)

    klass = instance.__class__
    qs_exists = klass.objects.filter(slug=slug).exists()
    if qs_exists:
        ne_slug = "{slug}-{randstr}".format(
            slug=slug,
            randstr=random_string_generator(size=4)
            )
        return unique_slug_generator(instance, new_slug=new_slug)
    return slug

this is my utils.py

Stack Trace

System check identified no issues (0 silenced).
April 20, 2020 - 16:27:28
Django version 3.0.5, using settings 'ecommerce.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
Internal Server Error: /admin/products/product/add/
Traceback (most recent call last):
  File "C:\ProgramData\Anaconda3\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
    response = get_response(request)
  File "C:\ProgramData\Anaconda3\lib\site-packages\django\core\handlers\base.py", line 115, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "C:\ProgramData\Anaconda3\lib\site-packages\django\core\handlers\base.py", line 113, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "C:\ProgramData\Anaconda3\lib\site-packages\django\contrib\admin\options.py", line 607, in wrapper
    return self.admin_site.admin_view(view)(*args, **kwargs)
  File "C:\ProgramData\Anaconda3\lib\site-packages\django\utils\decorators.py", line 130, in _wrapped_view
    response = view_func(request, *args, **kwargs)
  File "C:\ProgramData\Anaconda3\lib\site-packages\django\views\decorators\cache.py", line 44, in _wrapped_view_func
    response = view_func(request, *args, **kwargs)
  File "C:\ProgramData\Anaconda3\lib\site-packages\django\contrib\admin\sites.py", line 231, in inner
    return view(request, *args, **kwargs)
  File "C:\ProgramData\Anaconda3\lib\site-packages\django\contrib\admin\options.py", line 1638, in add_view
    return self.changeform_view(request, None, form_url, extra_context)
  File "C:\ProgramData\Anaconda3\lib\site-packages\django\utils\decorators.py", line 43, in _wrapper
    return bound_method(*args, **kwargs)
  File "C:\ProgramData\Anaconda3\lib\site-packages\django\utils\decorators.py", line 130, in _wrapped_view
    response = view_func(request, *args, **kwargs)
  File "C:\ProgramData\Anaconda3\lib\site-packages\django\contrib\admin\options.py", line 1522, in changeform_view
    return self._changeform_view(request, object_id, form_url, extra_context)
  File "C:\ProgramData\Anaconda3\lib\site-packages\django\contrib\admin\options.py", line 1565, in _changeform_view
    self.save_model(request, new_object, form, not add)
  File "C:\ProgramData\Anaconda3\lib\site-packages\django\contrib\admin\options.py", line 1081, in save_model
    obj.save()
  File "C:\ProgramData\Anaconda3\lib\site-packages\django\db\models\base.py", line 746, in save
    force_update=force_update, update_fields=update_fields)
  File "C:\ProgramData\Anaconda3\lib\site-packages\django\db\models\base.py", line 771, in save_base
    update_fields=update_fields,
  File "C:\ProgramData\Anaconda3\lib\site-packages\django\dispatch\dispatcher.py", line 175, in send
    for receiver in self._live_receivers(sender)
  File "C:\ProgramData\Anaconda3\lib\site-packages\django\dispatch\dispatcher.py", line 175, in <listcomp>
    for receiver in self._live_receivers(sender)
  File "F:\Ecom\DjangoEcommerce\products\models.py", line 69, in product_pre_save_receiver
    instance.slug = unique_slug_generator(instance)
  File "F:\Ecom\DjangoEcommerce\products\utils.py", line 22, in unique_slug_generator
    return unique_slug_generator(instance, new_slug=new_slug)
  File "F:\Ecom\DjangoEcommerce\products\utils.py", line 22, in unique_slug_generator
    return unique_slug_generator(instance, new_slug=new_slug)
  File "F:\Ecom\DjangoEcommerce\products\utils.py", line 22, in unique_slug_generator
    return unique_slug_generator(instance, new_slug=new_slug)
  [Previous line repeated 920 more times]
  File "F:\Ecom\DjangoEcommerce\products\utils.py", line 16, in unique_slug_generator
    qs_exists = klass.objects.filter(slug=slug).exists()
  File "C:\ProgramData\Anaconda3\lib\site-packages\django\db\models\query.py", line 777, in exists
    return self.query.has_results(using=self.db)
  File "C:\ProgramData\Anaconda3\lib\site-packages\django\db\models\sql\query.py", line 537, in has_results
    return compiler.has_results()
  File "C:\ProgramData\Anaconda3\lib\site-packages\django\db\models\sql\compiler.py", line 1121, in has_results
    return bool(self.execute_sql(SINGLE))
  File "C:\ProgramData\Anaconda3\lib\site-packages\django\db\models\sql\compiler.py", line 1138, in execute_sql
    sql, params = self.as_sql()
  File "C:\ProgramData\Anaconda3\lib\site-packages\django\db\models\sql\compiler.py", line 490, in as_sql
    extra_select, order_by, group_by = self.pre_sql_setup()
  File "C:\ProgramData\Anaconda3\lib\site-packages\django\db\models\sql\compiler.py", line 51, in pre_sql_setup
    self.setup_query()
  File "C:\ProgramData\Anaconda3\lib\site-packages\django\db\models\sql\compiler.py", line 42, in setup_query
    self.select, self.klass_info, self.annotation_col_map = self.get_select()
  File "C:\ProgramData\Anaconda3\lib\site-packages\django\db\models\sql\compiler.py", line 218, in get_select
    select.append((RawSQL(sql, params), alias))
  File "C:\ProgramData\Anaconda3\lib\site-packages\django\db\models\expressions.py", line 711, in __init__
    output_field = fields.Field()
  File "C:\ProgramData\Anaconda3\lib\site-packages\django\db\models\fields\__init__.py", line 156, in __init__
    if isinstance(choices, collections.abc.Iterator):
  File "C:\ProgramData\Anaconda3\lib\abc.py", line 139, in __instancecheck__
    return _abc_instancecheck(cls, instance)
RecursionError: maximum recursion depth exceeded in comparison
2
  • Could you add full error stacktrace? Usually there is the answer... Commented Apr 20, 2020 at 11:32
  • @Ralf thank you for your time as I mentioned I am new this I didn't find solution in other post Commented Apr 20, 2020 at 11:37

1 Answer 1

2

I suggest you try a while loop instead of recursion, because that is a lot more memory efficient than recursion and does not impact the programs stack.

Maybe something like this:

def unique_slug_generator(instance, new_slug=None):
    if new_slug is not None:
        slug = new_slug
    else:
        slug = slugify(instance.title)

    klass = instance.__class__

    while True:
        if not klass.objects.filter(slug=slug).exists():
            return slug

        slug = "{slug}-{randstr}".format(
            slug=slug,
            randstr=random_string_generator(size=4)
            )
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.