Django NoReverseMatch at /school/new-school/ - python

What is wrong with my approach?
When I post new data, I want it to return back to the page with the input fileds empty. But it gives me this error
NoReverseMatch at /school/new-school/
Reverse for 'new-school' with arguments '()' and keyword arguments '{}' not found. 0 pattern(s) tried: []
This is my model. Please note, reverse_lazy was imported
class SchoolList(models.Model):
name = models.CharField(max_length=15, null=False)
def __str__(self):
return '%s' % (self.name)
def get_absolute_url(self):
return reverse_lazy('new-school')
This is my url.py
url(r'^school-list/$', SchoolListtView.as_view(), name='school-list'),
url(r'^new-school/$', CreateSchoolListView.as_view(), name='new-school'),
url(r'^school(?P<pk>\d+)/update/$', SchoolListUpdate.as_view(), name='update-school')
This is my view for create.
class CreateSchoolListView(CreateView):
template_name = 'school\create_form.html'
model = SchoolList
fields = ['name']
This is how I specified the urls in the template.
Create New School
View all Schools
When the page is displayed, I can click the links and it will go to the correct pages. But when I post a data, the it throws the above error. I have been on this for hours and read many of the answers online. It seems mine is a unique case.

Try adding namespace to get_absolute_url().
def get_absolute_url(self):
return reverse_lazy('school:new-school')

Make sure you import your app's urls in your project's urls with namespace like:
url(r'^school/', include('school.urls', namespace="school"))
to use namespace in your templates like this:{% url 'school:new-school' %}
Or remove namespace:
url(r'^school/', include('school.urls'))
to use url without namespace in template:{% url 'new-school' %}
Using get_absolute_url would be a bad approach in this case, since it's an instance method, designed to get url for single model instance.
If you want to add method to model, you should use something like this:
#classmethod
def get_create_url(cls):
return reverse_lazy('school:new-school')

Related

Django 2.0 UpdateView NoReverseMatch

PLEASE IGNORE!
Trying to use UpdateView to update a model object with name "Tag"
Here is the model:
NAME_REGEX = r'^[a-zA-Z0-9\s.\-]+$'
class Tag(TimeStampModel):
name = models.CharField(max_length=40,
validators = [
RegexValidator(regex=NAME_REGEX,
message='name must be alphanumeric, may contain - _',
code='invalid tag name')],
unique=True)
slug = models.SlugField(max_length=60, unique=True, blank=True)
text = models.TextField(blank=True)
def __str__(self):
return self.name
def get_absolute_url(self):
url = reverse('tags:tag_detail', kwargs={'slug':self.slug})
print('Tag *************** 010 ********************')
print(url)
return url
def save(self, *args, **kwargs):
self.slug = make_slug(self.name)
super().save()
I am able to create a Tag using CreateView, list the Tags using ListView and access the Tag detail using DetailView. I am also able to edit the tag using a function based view. However, it falls down with UpdateView.
Here are the urls:
urlpatterns = [
path('', views.IndexView.as_view(), name='index'),
path('tag_list/', views.TagListView.as_view(), name='tag_list'),
path('tag_detail/<slug:slug>/', views.TagDetailView.as_view(),
name='tag_detail'),
path('create_tag/', views.CreateTagView.as_view(),
name = 'create_tag'),
path('update_tag/<slug:slug>/', views.UpdateTagView.as_view(),
name = 'update_tag'),
path('category_list/', views.CategoryListView.as_view(),
name = 'category_list'),
path('category_detail/<slug>/', views.CategoryDetailView.as_view(),
name = 'category_detail'),
]
In a template called "tag_detail.html" I provide a link that should take the user to an edit form as follows:
<p class="slm-red">
{{ tag_dict.slug }}
<br>
Edit Tag
</p>
(I've printed the value of the slug before the link. That is not the problem. The slug value is correct. in this case slug = "brown")
When I click the link it takes me to:
http://localhost:8000/tags/update_tag/brown/
In this case the slug has the value "brown"
I get the following error message:
Reverse for 'update_tag' with no arguments not found. 1 pattern(s) tried: ['tags\\/update_tag\\/(?P<slug>[-a-zA-Z0-9_]+)\\/$']
I tried it the old fashioned way using "url" instead of path and a regular expression for the slug with the same result.
It all works fine when I use a function based view passing slug as a parameter.
Here is the UpdateTagView:
class UpdateTagView(UpdateView):
print('UpdateTagView ************** 010 *****************')
template_name = 'tags/update_tag.html'
model = Tag
fields = ['text']
The first line is a print statement. It does not appear on the console log so this confirms that Django never gets as far as the actual view. What I do get on the console log includes the following:
[22/Jan/2018 16:06:00] "GET /tags/tag_detail/brown/ HTTP/1.1" 200 4852
Internal Server Error: /tags/update_tag/brown/
I've tried several variants but nothing works. I am getting quite desperate.
I've seen similar questions on stack overflow for previous versions of Django but there never seems to be an answer.
When I use an FBV it's simple. I just pass the slug as a parameter along with request.
For what it's worth the errors seems to be occurring in base.py. At the end of the error messages I see:
C:\django\_dj\projenv\lib\site-packages\django\urls\base.py in reverse
I think there's a kwarg I'm supposed to override but I have no notion how to do it. Since Django never gets as far as the UpdateTagView nothing I do there can affect the outcome.

Django redirecting url with changed values

I have urls that take a parameter called board_slug. Before getting the template the view will replace the slug if its name is wrong and redirect it. I have already made the code for fixing the slug but do not know how insert the fixed board_slug into the new url. This code is run across multiple views so it has to work with all the following kinds urls:
url(r'^boards/(?P<board_slug>[^/]+)/$', views.BoardView.as_view(), name='board'),
url(r'^/front-thing/boards/(?P<board_slug>[^/]+)/new/$', views.BoardView.as_view(), name='new_board'),
url(r'^boards/(?P<board_slug>[^/]+)/etc...$', views.BoardView.as_view(), name='anything_with_board'),
class BoardView(View):
template_name = 'forums/board.html'
def get(self, request, board_slug):
if wrong:
url = get_django_url
url.board_slug = 'new-slug'
return redirect(url)
else:
return template

NoReverseMatch django - not a valid view function or pattern

Currently using Django 1.11. I get an exception of
Reverse for 'book_details' not found. 'book_details' is not a valid view function or pattern name.
Request Method: GET
Request URL: http://localhost:8000/library/book/c7311ecf-eba7-4e9d-8b1a-8ba4e075245a/
Django Version: 1.11
Exception Type: NoReverseMatch
I want to use the get_absolute_url from my Model in the details page to go to a Update page. When I take out the reference to the .id and use the get_absolute_url. I checked to see the name "book_details" is referenced properly. I can go to the page and have books details render properly. In the admin console of Django, the "view on site" button also does not render properly it shows this localhost:8000/admin/r/13/c7311ecf-eba7-4e9d-8b1a-8ba4e075245a/ so it does not get the library/books either
current
Update
desired
Update
Where have I mistyped for this to not work?
Setup in files:
Yes, I do have UUID as the primary key.
In views.py
class BookDetailsView(generic.DetailView):
"""
Generic class-based detail view for a Book.
"""
model = Book
in urls.py
url(r'^book/(?P<pk>[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$', views.BookDetailsView.as_view(), name='book_details'),
url(r'^book/(?P<pk>[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/update/$', views.BookUpdate.as_view(), name='book_update'),
in models.py
class Book(models.Model):
def get_absolute_url(self):
"""Returns the URL of the book for details"""
return reverse('book_details', args=[str(self.id)])
Try providing the pk as keyword argument to the reverse function,
def get_absolute_url(self):
return reverse('book_details', kwargs={ 'pk': str(self.id) })
Also, you are missing a trailing slash at the end of the url,
url(r'^book/(?P<pk>[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/$', views.BookDetailsView.as_view(), name='book_details'),

readonly_fields returns empty value in django inlined models

i am new in django framework, in my current try, i have two models (Client and Facture). Facture is displayed as a TabularInline in client change view.
i want display a link for each inlined facture object to download the file. so i added a custom view that download the facture file, but dont know how to link to it
class Client(models.Model):
...
class Facture(models.Model):
client = models.ForeignKey(Client, on_delete=models.CASCADE)
numero = models.IntegerField(unique=True, default=rand_code)
...
and in the admin.py:
class FactureInline(admin.TabularInline):
model = Facture
extra = 0
readonly_fields = ('numero', 'dl_link')
def DLFacture(self, request, obj):
...
response.write(pdf)
return response
def get_urls(self):
urls = super(FactureAdmin, self).get_urls()
from django.conf.urls import url
download_url = [
url(r'^(?P<pk>\d+)/download/$', self.admin_site.admin_view(self.DLFacture), name="download"),
]
return download_url + urls
def dl_link(self, obj):
from django.core.urlresolvers import reverse
return reverse("admin:clients_facture_download", args=[obj.pk])
admin.site.register(Facture, FactureAdmin)
class ClientAdmin(admin.ModelAdmin):
inlines = [
FactureInline,
]
admin.site.register(Client, ClientAdmin)
i get the following error:
Reverse for 'clients_facture_download' with arguments '(1,)' and keyword arguments '{}' not found. 0 pattern(s) tried: []
all works fine when i change the reverse url to
reverse("admin:clients_facture_change", args=[obj.pk])
so any one could help me know how to reverse the download view and if i am doing thinks right ?
thanks for any help
Firstly, you are using name='download', but trying to reverse clients_facture_download.
I would try changing the url from
url(r'^(?P<pk>\d+)/download/$', self.admin_site.admin_view(self.DLFacture), name="download"),
to
url(r'^(?P<pk>\d+)/download/$', self.admin_site.admin_view(self.DLFacture), name="clients_fracture_download"),
Secondly, InlineModelAdmin does not have a get_urls method. You should move it to your ClientAdmin class.
I would think you need to reverse the order in the url:
url(r'^download/(?P<pk>\d+)$', self.admin_site.admin_view(self.DLFacture), name="download"),
]

How do I use DateDetailView with a slug to render a page with a single article?

I am new to Django, and I am trying to have a separate page where I can view individual articles. Currently I have:
#views.py
class ArticleView(DateDetailView):
template_name = 'blog/article.html'
model = Article
date_field = "pub_date"
#I am not sure which one to use
slug_field = "unique_url_suffix"
slug_url_kwarg = 'unique_url_suffix'
and
#urls.py
urlpatterns = [
url(r'^(index\.html)?$',views.IndexView.as_view(),name='index'),
url(r'^(?P<year>[0-9]{4})/(?P<month>[-\w]+)/(?P<day>[0-9]+)/(?P<slug>[-\w]+)/$',
views.ArticleView.as_view(),
name="article_detail"),
]
and in index.html inside a loop of objects from the Article class:
<h2>{{article.title}}</h2>
I have also tried manually inputting the arguments, like this:
<h2>{{article.title}}</h2>
I keep on getting a "NoReverseMatch at /blog/" error. What am I doing incorrectly?
Edit: On top of the changes recommended for the answer, there was a typo causing problems. It does not affect the answer below, though.
First off, you should not be generating this URL in your template. You should define a get_absolute_url method in your Article model that looks like this:
from django.core.urlresolvers import reverse
def get_absolute_url(self):
# Note - you have to supply each of the date components separately
# because you need to match the URL regex.
return reverse (
'blog:article_detail',
kwargs={'year': self.pub_date.strftime("%Y"), 'month': self.pub_date.strftime("%b"),
'day': self.pub_date.strftime("%d"), 'slug': self.unique_url_suffix}
)
And then in your template:
<h2>{{article.title}}</h2>

Categories