0

I encountered a No Reverse Match Error in trying to render a template. Can you explain what this No Reverse Match Error mean for easier understanding and how to solve the error?

models.py

from django.contrib.sites.models import Site
from django.contrib.gis.db import models
from django.utils.crypto import get_random_string
from django.contrib.gis.geos import GEOSGeometry,Point
from django.contrib.auth.models import AbstractUser
from django.shortcuts import render
# Create your models here.
class User(AbstractUser):
    pass

geos_pnt=Point(4314498.56, 1003834.600,srid=3857)
#pnt=GEOSGeometry('POINT(4314498.56, 1003834.600)').wkt
class Apartment(models.Model):
    SUBCITY_CHOICES = (
    ('ADK', 'Addis Ketema'), ('AKLTY', 'Akaki-Kality'), ('ARD', 'Arada'), ('BL', 'Bole'), ('GL', 'Gulele'),
    ('KLF', 'Kolfe-Keranio'), ('LDTA', 'Ledeta'), ('NFS', 'Nefas Silk'), ('YK', 'Yeka'))
    apt_id = models.CharField(str(SUBCITY_CHOICES)+"-"+get_random_string(length=4), max_length=8,primary_key=True)
    location = models.PointField(default=geos_pnt,extent=(4282586.10,996190.90,4346411.02,1011478.31),
                                    blank=True, null=True, srid=3857, help_text="Point(longitude latitude)")
    no_bedrooms= models.IntegerField(null=True)
    apt_area = models.IntegerField(default=0, null=True)
    apt_cost = models.IntegerField(default=0, null=True)
    apt_subcity = models.CharField(default='Nefas Silk',max_length=100, choices=SUBCITY_CHOICES,null=True)
    register_date = models.DateTimeField('Register Date',auto_now_add=True,null=True)
    slug = models.SlugField(unique=True)
    objects = models.Manager()
    sites =models.ManyToManyField(Site)

    #change points from apt_rent_db to kml
    def pointkml(self):
        points = Apartment.objects.kml()
        return render("placemarks.kml", {'places': points})
    def get_absolute_url(self):
        return reverse('apartment_create', kwargs={'pk': self.pk, 'apt_id': self.apt_id.pk})

    def save(self, *args, **kwargs):
        #self.Latitude = self..y
        #self.Longitude = self.location.x
        self.slug = slugify(self.apt_id)
        super(Apartment, self).save(*args, **kwargs)

    class Meta:
       # order of drop-down list items
       verbose_name = ("Apartment")
       verbose_name_plural = ("Apartments")
       ordering = ('apt_cost',)
       app_label = 'rent_app'

    def __unicode__(self):
        return self.apt_id

urls.py:

from django.urls import path
from . import views
app_name = 'rent_app'


    urlpatterns = [

            path('', views.IndexView.as_view(), name='index'),
            path('apartment_create/<slug:apt_id>)', views.ApartmentCreate.as_view(), name='apartment_create'),
            path('apartments/<int:pk>/', views.ApartmentUpdate.as_view(), name='apartment_update'),
            path('apartments/<int:pk>/delete/', views.ApartmentDelete.as_view(), name='apartment_delete'),
             ]

views.py:

from django.urls import reverse_lazy
from django.views import generic
from django.views.generic.edit import CreateView, DeleteView, UpdateView
from .models import Apartment
from .forms import ApartmentCreateForm


class IndexView(generic.ListView):

    template_name = 'djnago_leaflet.html'
    context_object_name = 'latest_apartments_list'

    def get_queryset(self):

        """Return the last five published apartments."""

        return Apartment.objects.order_by('-register_date')[:5]

class ApartmentCreate(CreateView):
    template_name = 'rent_app/apartment-create-success.html'
    form_class = ApartmentCreateForm
    fields = ['apt_id','location','apt_area','apt_cost']
    success_url= reverse_lazy('apartment-create')

class ApartmentUpdate(UpdateView):
    model = Apartment
    fields = ['apt_id','location','apt_area', 'apt_cost']
    template_name='index_leaflet.html'
    template_name_suffix='apartments'

class ApartmentDelete(DeleteView):
    model = Apartment
    template_name = 'index_leaflet.html'
    template_name_suffix='apartments'
    success_url = reverse_lazy('apartment-list')

the html:

<html>
  <head>
   {% leaflet_js plugins="forms" %}
   {% leaflet_css plugins="forms" %}
  </head>


  <body>

    {% leaflet_map "map" callback="window.map_init_basic" %}
    <h2>Edit Apartment ID {{ Apartment.apt_id }}</h2>
    <h2>Edit Apartment Location {{ Apartment.location }}</h2>
    <form action="{% url 'rent_app:apartment_create' apt_id %}" method="post">
        {% csrf_token %}
        {{ form }}
        <input type="submit"/>
    </form>
  </body>
</html>
3
  • add your apartment_create url and the view that renders the html you added. Also add the error. Commented Feb 17, 2020 at 6:11
  • It means that Django's url resolver was not able to find a url with the required name. Specifically: In your urls.py there is probably no url pattern with the name "apartment_create" or you have not set the namespace "rent_app". Commented Feb 17, 2020 at 7:16
  • @Chris I believe I have set the namespace if the namespace meant app_name. There is also a url with the name apartment_create in urls.py Commented Feb 17, 2020 at 9:16

1 Answer 1

1

I think there are a number of issues in your code.

First regarding the error you are seeing. In your urls you have defined a pattern with the name 'apartment_create' which expects a slug as a parameter. However, apt_id in your template is an empty field. So django cannot find a pattern with the name 'apartment_create' and a valid slug. To solve this change the url pattern to

path('apartment_create/', views.ApartmentCreate.as_view(), name='apartment_create')

And in your template either take out the apt_id from your action in the form (or take out the action all together.

However, in your ApartmenCreate view you are missing the model parameter. In addition the fields and the form parameter are redundant. And are you sure the template_name parameter in that view is correct?

In your model the field apt_id looks strange. You are creating a field with some very obscure verbose_name. If you want to have a choice field you have to set the choices parameter of the field, e.g.:

apt_id = models.CharField(choices=SUBCITY_CHOICES, max_length=8, primary_key=True)

Your get_absolute_url is also not correct: First of all there is no valid url matching that pattern and secondly a field (apt_id) does not have a pk.

In your template you have statements like {{ Apartment.apt_id }}. However, Apartment is a class. So in your views add context_object_name='apartment' so you can access the values in your template like so {{ apartment.apt_id }}.

There are probably some other issues which I have overlooked.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you @Chris for the through CodeReview.
No problem, was a pleasure

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.