0

I am encountering the error message similar to this post here.

However, I received this message only after I have done the following steps to my django model instances, particularly in the admin.

I have a model, called "Product". In admin, I create a few instances of this Product, each with an "id" field. So, I have 5 products, each with "id" "1", "2", "3", "4" and "5".

I have an html template that displays the list of all "products", with a url link to each product given by this:

class Product(models.Model)
   ...
   def get_absolute_url(self):
        return reverse('catalog:product_detail',
                       args=[self.id, self.slug])

Here is that part of the template:

<a href="{{ product.get_absolute_url }}"> </a>

Clicking this url brings to a product detail view as following (in views.py):

def product_detail(request, id, slug):
    product = get_object_or_404(Product,
                                id=id,
                                slug=slug)    

    return render(request,
                  'catalog/product/detail.html',
                  {'product': product,})

I also created a context processor to keep track of the products created in all templates in this website in a context_processors.py.

Now, when I delete the first few products in admin (product "1", "2", "3"), and at the same time, create new products in admin (add "6", "7", "8" and "9"), when I re-render the template, I got this "NoReverseMatch" error.

I am guessing that since the products get removed in admin, but the context process still keeps a record of that products, the template could not find the reverse url anymore. How do I "reset" this situation (i.e. reset all my products or the context processors)?

Tristan Tran
  • 1,351
  • 1
  • 10
  • 36

1 Answers1

0

i guess you have an app called catalog in which you defined Product model

i think, you don't even need the id since slug have to be unique obviously (in Product model)

class Product(models.Model):
    """Model to store Products."""

    slug = models.SlugField(_('slug'), max_length=255,
        unique=True, null=True, blank=True,
        help_text=_(
            'If blank, the slug will be generated automatically '
            'from the given name.'
        )
    )


    name = models.CharField(_('name'), max_length=255,
        unique=True,
        help_text=_('The title of the product.')
    )

    [..]

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.name)
        super(Product, self).save(*args, **kwargs)

in your function

def product_detail(request, slug):
    product = get_object_or_404(Product, slug=slug)

    return render(request,
                  'catalog/product/detail.html',
                  {'product': product,})

you can define your route like

app_name = 'catalog'
urlpatterns = [
..
    path('products/<slug:slug>', views.product_detail, name='product_detail'),
..
]

and then in your template call the url

<a href="{% url 'catalog:product_detail' slug=product.slug %}"> </a>
cizario
  • 3,995
  • 3
  • 13
  • 27
  • Thanks for the detailed help. I have just done a "clean-slate", nuked my database, re-created the database and re-migrated. It solves my problem. – Tristan Tran Jul 09 '20 at 08:21