No Reverse Match - python

Reverse for 'details' with arguments '('Federal Airports Authority of Nigeria (FAAN)',)' and keyword arguments '{}' not found.
1 pattern(s) tried:
['details/(?P<company_name>[0-9A-Za-z]+)/$']
This is my urls.py
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^details/(?P<company_name>[0-9A-Za-z]+)/$', views.details, name='details'),
url(r'^full_list/$', views.full_list, name='full_list' ),
]
This is the models.py
class CompanyDetail(models.Model):
name = models.CharField(max_length=300)
company_logo = models.FileField(default='')
company_info = models.TextField()
company_address = models.TextField()
tag = models.CharField(max_length=300)
def __str__(self):
return self.name
This is my views.py
def details(request, company_name):
company = CompanyDetail.objects.get(name=company_name)
return render(request, 'company_profiles/details.html',
{'company':company} )
def full_list(request):
lists = CompanyDetail.objects.all()
return render(request, 'company_profiles/full_list.html',
{'lists':lists})
This is the template :
{% extends 'company_profiles/base.html' %}
{% block content %}
{% for company in lists %}
<p>
<div class="alert alert-info" role="alert">
{{ company }}
</div>
</p>
{% empty %}
<p>No companies found</p>
{% endfor %}
{% endblock content %}
I only get no reverse match when there are spaces in the company name.

That's because your regex
(?P<company_name>[0-9A-Za-z]+)
doesn't allow for spaces in the company name. Django correctly tells you there is no reverse match.
Pick one of the options below:
Change the name validation code to disallow spaces (and migrate existing rows), or
Change the regex in urls.py to allow spaces
I recommend the second option.

You should try this in urls.py for match company name
(?P<company_name>[\w-]+)
and also one thing why you are not using Company ID as a parameter? like below:
in urls.py
(?P<company_id>[0-9]+)/
in templates
<a href="{% url 'company_profiles:details' company.pk %}"
class="alert-link">{{ company }}</a>

Related

Django - Reverse for 'topic' with arguments '('',)' not found. 1 pattern(s) tried: ['(?P<topic>[^/]+)/\\Z']

I'm learning Django and there was a problem. I will be grateful if you help
Reverse for 'topic' with arguments '('',)' not found. 1 pattern(s) tried: ['(?P[^/]+)/\Z']
views:
def topic(request, topic):
topic = New_topic.objects.get(id=topic)
comments = topic.comment_set.order_by('+date')
context = {'topic':topic, 'comments':comments}
return render(request, 'topic.html', context)
urls:
from django.urls import path
from . import views
app_name = "forum"
urlpatterns = [
path('', views.main, name='main'),
path('<int:topic>/', views.topic, name='topic')
]
models:
from django.db import models
from django.contrib.auth.models import User
class New_topic(models.Model):
text = models.CharField(max_length=64)
date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.text
class Comments(models.Model):
topic = models.ForeignKey(New_topic, on_delete=models.CASCADE)
text = models.TextField()
date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.text
template:
main.html
{% block content %}
{% for list_forum in list %}
{{ list_forum }}
{% endfor %}
{% endblock content %}
topic.html
{% block content %}
{{ topic }}
{% for comment in comments %}
{{ comment.text|linebreaks }}
{% endfor %}
{% endblock content %}
Try path('<topic>/<int:pk>/', views.topic, name='topic')
I just reassigned the app url from "index" to "forum"
path('', include('forum.urls')) to change path('forum/', include('forum.urls'))

How can I lists all the products according to their foreign key?

I am working on my first eshop website using django framework and I got stuck on a problem.
I have created a general model for different kinds of products (like laptops, books etc.). Each product that is added to the website can be found by on its foreign key that links that product to a specific category.
The question is how can I display on laptops.html only the products that have the foreign key which points to the right category? Like, to display only the products from laptops category.
Thank you very much for your time!
EDIT:
in urls:
urlpatterns=[
path('', views.HomePage.as_view(), name='home'),
path('ComputerScience/', views.ComputerScience.as_view(), name='computer_science'),
path('category/<int:category_pk>/list-products/', views.CompSProd.as_view(), name='category_products_list')]
In computerscience.html I render all the cateogries.
Here in views.py I have the two controllers, first for categories and second for laptops for instance.
views.py
class ComputerScience(ListView):
model = ComputerScienceCategory
template_name = "computer_science.html"
context_object_name = "category"
class CompSProd(ListView):
model = ComputerScienceProducts
template_name = "laptops.html"
context_object_name = "products"
def get_queryset(self):
queryset = super().get_queryset()
# If you wish to still keep the view only for specific category use below line
category = get_object_or_404(ComputerScienceCategory, pk=self.kwargs.get('category_pk'))
queryset = queryset.filter(category=category)
return queryset
Here I have the template where I want to display all categories.
computer_science.html
<div class="computerScienceContent" id="slide">
{% for cat in category %}
<a href="{% url 'category_products_list' category.pk %} " id="aBar">
<div>
<h4 class="cSh">{{ cat.name }}</h4>
<img src="{{ cat.img.url }}" alt="image" class="img">
</div>
</a>
{% endfor %}
Here is laptops html, where I'd like to have the whole products displayed.
laptops.html
{% extends 'index.html' %}
{% block title %}
<title>Laptops</title>
{% endblock %}
{% block cont2 %}
{% endblock %}
My main goal is that to have a page (computerscience.html) where I have displayed a list with all available categories and when you click on one category, to redirect you to another page where you have listed all the products that belongs to that category.
This is the error that has been thrown to me:
Reverse for 'category_products_list' with arguments '('',)' not found. 1 pattern(s) tried: ['category/(?P<category_pk>[0-9]+)/list\\-products/$']
You should override get_queryset to filter your objects. Also as you are writing a view for a specific instance of category you would end up writing a lot of views, also when a new category would be added this would be very tedious you should use one view for all categories instead. Try this:
from django.shortcuts import get_object_or_404
class CompSProd(ListView):
model = ComputerScienceProducts
template_name = "laptops.html"
context_object_name = "products"
def get_queryset(self):
queryset = super().get_queryset()
category = get_object_or_404(ComputerScienceCategory, pk=self.kwargs.get('category_pk')) # Assuming category_pk will be passed in url
# If you wish to still keep the view only for specific category use below line
# category = get_object_or_404(ComputerScienceCategory, pk=<pk-of-category-here>)
queryset = queryset.filter(category=category)
return queryset
To pass the categories primary key in the url you need to do something as follows:
In your urls.py:
urlpatterns = [
...
path('category/<int:category_pk>/list-products/', views.CompSProd.as_view(), name='category_products_list'),
...
]
Now in the page where you display all categories:
{% for cat in category %}
<a href="{% url 'category_products_list' cat.pk %}" id="aBar">
<div>
<h4 class="cSh">{{ cat.name }}</h4>
<img src="{{ cat.img.url }}" alt="image" class="img">
</div>
</a>
{% endfor %}
Also you write id="aBar" but this line is in a loop meaning you would end up with multiple same ids you should use a class instead.

NoReverseMatch Django 2 Python

NoReverseMatch
Reverse for 'Edit_Product' with no arguments not found. 1 pattern(s) tried: ['shop/product/Edit_Product/(?P[0-9]+)$']
I could not understand the reason behind this error I tried looking for answers for around the web but nothing worked for me so far, I am new to django and trying to develop my skills if anyone can help please
Models.py
class Product(models.Model):
category = models.ForeignKey(Category,
related_name='products',
on_delete=models.CASCADE)
name = models.CharField(max_length=200, db_index=True)
slug = models.SlugField(max_length=200, db_index=True)
image = models.ImageField(upload_to='products/%Y/%m/%d',
blank=True)
description = models.TextField(blank=True)
price = models.DecimalField(max_digits=10, decimal_places=2)
available = models.BooleanField(default=True)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
class Meta:
ordering = ('name',)
index_together = (('id', 'slug'),)
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('shop:product_detail', args=[self.id, self.slug])
forms.py
class EditProduct(forms.ModelForm):
class Meta:
model = Product
fields = ["category", "name", "image", "description",
"price", "available"]
views.py
#staff_member_required
def Edit_Product(request, id=None):
product = get_object_or_404(Product, id=id)
if request.method == "POST":
form = EditProduct(request.POST, instance=product)
if form.is_valid():
form = form.save(commit=False)
form.save()
return render(request, 'shop/product/Edit_Product.html', {'product': product, 'form':form})
else:
form = EditProduct(instance=product)
return render(request,'shop/product/Edit_Product.html', {'form': form})
urls.py
urlpatterns = [
path('', views.product_list, name='product_list'),
path('<slug:category_slug>/', views.product_list, name='product_list_by_category'),
path('<int:id>/<slug:slug>/', views.product_detail, name='product_detail'),
path('shop/Create_Product/', views.Create_Product, name='Create_Product'),
path('shop/product/Edit_Product/<int:id>', views.Edit_Product, name='Edit_Product'),
]
the templates look like this
{% extends "shop/base.html" %}
{% load static %}
<title> Edit </title>
{% block content %}
<div>
<form action="{% url 'shop:Edit_Product' id=Product.id %}" method="POST" enctype="multipart/form-data">
{{ form.as_p }}
<p><input type="submit" value="Update"></p>
{% csrf_token %}
</form>
</div>
{% endblock %}
I would be really grateful for any help I have been having for days now and when modifying it I receive either this error or 404 error.
the error is showing me the detailproduct view in the browser I tried arranging them making edit before it and add it to the render line but alos no luck there
This is how it looks like the view.py product detail just after the edit
def product_detail(request, id, slug):
product = get_object_or_404(Product,
id=id,
slug=slug,
available=True)
cart_product_form = CartAddProductForm()
return render(request,
'shop/product/detail.html',
{'product': product,
'cart_product_form': cart_product_form})
the Image link is here for the Error
enter image description here
Detail.html
{% block content %}
<div class="product-detail">
<img src="{% if product.image %}{{ product.image.url }}{% else %}{% static "img/no_image.png" %}{% endif %}">
<h1>{{ product.name }}</h1>
<h2>{{ product.category }}</h2>
<p class="price">${{ product.price }}</p>
<form action="{% url "cart:cart_add" product.id %}" method="post">
{{ cart_product_form }}
{% csrf_token %}
{% if request.user.is_staff %}
Edit Product
{% endif %}
<input type="submit" value="Add to cart">
</form>
{{ product.description|linebreaks }}
You should try to understand the error:
NoReverseMatch Reverse for 'Edit_Product' with no arguments not found.
This error is saying that you asked Django to reverse a url pattern with the name Edit_Product, that it expects an argument but no argument was given.
Indeed, this is your path:
path('shop/product/Edit_Product/<int:id>', views.Edit_Product, name='Edit_Product')
so in order to reverse it, you need to pass it the argument id:
# in a view
from django.urls import reverse
reverse('Edit_Product', kwargs={'id': <some_id>})
# in a template
{% url 'Edit_Product' id=<some_id> %}
You can now just search in your entire project for reverse('Edit_Product' and {% url 'Edit_Product' or narrow it down like this:
First, this is not an error in your Edit_Product view (at least not necessarily), it can happen in any view that reverses the url pattern. You need to look at the rest of the error message which tells you which url was requested or which view was used.
You already saw that this was happening in the product_detail() view, in the render() method actually.
So the error was triggered when rendering the template, in this case the detail.html template. Here you should check for {% url 'Edit_Product' ... %}.
There you have it, {% url 'Edit_Product' %} with no argument. Fix it by adding the product.id.

blog/posts.category.get_absolute_url, didn't match any of these

I am stuck at url problem. I suppose it is because of my 'blog.urls', or the href is my 'models.py'.But I am not sure how to change it. I am a programmer beginner. Sorry for the question if it is too simple.
The issue is:
Page not found (404)
Request Method: GET
Request URL: http://127.0.0.1:8000/blog/posts.category.get_absolute_url
Using the URLconf defined in djangotest.urls, Django tried these URL patterns, in this order:
admin/
blog/ [name='list_of_post']
blog/ <slug:slug>/ [name='post_detail']
blog/ category/<slug:slug>/ [name='list_of_post_by_category']
The current path, blog/posts.category.get_absolute_url, didn't match any of these.
blog/urls:
from django.conf.urls import url
from django.urls import path
from . import views
app_name = 'blog'
urlpatterns =[
path('',views.list_of_post,name='list_of_post'),
path('<slug:slug>/',views.post_detail,name='post_detail'),
path('category/<slug:slug>/',views.list_of_post_by_category,name='list_of_post_by_category')
]
list_of_post.html:
{% extends 'blog/post/base.html' %}
{% block title %}List of blog post{% endblock %}
{% block content %}
{% for posts in post %}
<h2>{{ posts.title }}</h2>
<p>Written by {{ posts.author }} on {{ posts.published}} in {{posts.category}}</p>
<hr>
{{ posts.content | truncatewords:40 | linebreaks}}
{% endfor %}
{% endblock %}
model.py:
class Category(models.Model):
name = models.CharField(max_length = 250)
slug = models.SlugField(max_length=250,unique=True)
class Meta:
ordering = ['name']
verbose_name = 'category'
verbose_name_plural = 'categories'
def get_absolute_url(self):
return reverse('blog:list_of_post_by_category',args=[self.slug])
def __str__(self):
return self.name
Since posts.category.get_absolute_url is a variable, it has to be enclosed inside curly braces:
{{posts.category}}
Also, {% for posts in post %} looks kind of weird. Are you passing a list of posts as post from the view? I would recommend it to be posts, and the condition will then change to {% for post in posts %}

How do I iterate through a ManyToManyField in django-jinja project?

I am trying to create a blog app which has posts and each posts have title, date, link and tags.
This is my models.py
# models.py
from django.db import models
class Tag(models.Model):
name = models.CharField(max_length=20)
def __str__(self):
return self.name
class Meta:
ordering = ('name',)
class Post(models.Model):
title = models.CharField(max_length=300)
date = models.DateTimeField()
link = models.URLField()
tags = models.ManyToManyField(Tag)
def __str__(self):
return self.title
#property
def tags_name(self):
return [x.name for x in self.tags]
class Meta:
ordering = ('date',)
This is my views.py
# views.py
from django.conf.urls import url, include
from django.views.generic import ListView
from blog.models import Post
urlpatterns = [
url(r'^$', ListView.as_view(queryset=Post.objects.all().order_by("-date"), template_name="blog/blog_list.html")),
]
This is my blog_list.html
<!-- blog_list.html -->
{% extends "mysite/layout.html" %}
{% block content %}
<h1>my blog posts</h1>
<ul>
{% for post in object_list %}
<li><span class="title">{{ post.title }}</span></li>
<p>{{ post.date|date:"d-m-Y" }}</p>
{% endfor %}
</ul>
{% endblock %}
{% block sidebar %}
<h4 id="sidenav">tags</h4>
{% for post in object_list %}
<ul>
<!-- I want to show the tags here -->
</ul>
{% endfor %}
{% endblock %}
In the blog_list.html, I am showing all the post details and on the sidebar, I want to show all the tags present from all the blog posts available. Since post.tags is ManyToManyField, how can I iterate through it?
You want to use .all in the template to get all the elements in the relationship:
{% for tag in post.tags.all %}
{{ tag }}
{% endfor %}
Thanks to #hansTheFranz for correcting my bracket issue.
Regarding not repeating tags, this would be very difficult with the current context. You might want to look into instead getting the posts in your View and extracting the tags there, where you have more freedom to check for duplicates. Something like this:
def tags(request):
posts = Post.objects.all()
tag_list = []
for post in posts:
tags = post.tags.all()
for tag in tag:
if not (tag in tag_list):
tag_list.append(tag)
context_dict = { "tags": tag_list, "posts": posts }
return render(request, 'blog/blog_list.html', context_dict)
urlpatterns = [
url(r'^$', tags, name="tags"),
]
And then change your template to be more like:
{% block sidebar %}
<h4 id="sidenav">tags</h4>
<ul>
{% for tag in tags %}
<li>{{ tag }}</li>
{% endfor %}
</ul>
{% endblock %}
Additionally, instead of referencing object_list you can now access the list of posts by referencing posts, because we have defined the list of posts as such in our context dictionary, which is being passed to the template.
I'm afraid I have not tested this and it may not be very efficient, but roughly speaking it should work. A lecturer at my university wrote this book: http://www.tangowithdjango.com/book17/, which encourages more of a style of writing views as I have done: separate from the URLs. If anything I've done seems unclear or contrary, you may want to have a look at the book and see if anything there makes more sense.

Categories

Resources