I'm new to Django and programming in general. I'm going through the book Django For Beginners and have added my own flair in the forms section but have run into a problem. Below I have detailed the error and provided my code.
ERROR
NoReverseMatch at /drug/12/
Reverse for 'drug_edit' with keyword arguments '{'pk': ''}' not found. 1 pattern(s) tried: ['drug/(?P[0-9]+)/edit/$']
Request Method: GET
Request URL: http://127.0.0.1:8000/drug/12/
Django Version: 3.1.3
Exception Type: NoReverseMatch
Exception Value:
Reverse for 'drug_edit' with keyword arguments '{'pk': ''}' not found. 1 pattern(s) tried: ['drug/(?P[0-9]+)/edit/$']
Exception Location: C:\Users\scott\django_sites\history_cloud1\history1_env\lib\site-packages\django\urls\resolvers.py, line 685, in _reverse_with_prefix
Python Executable: C:\Users\scott\django_sites\history_cloud1\history1_env\Scripts\python.exe
Python Version: 3.8.3
models.py
from django.db import models
from django.urls import reverse
class DrugInfo(models.Model):
drug_name = models.CharField(max_length=75)
patient_name = models.CharField(max_length=25, default='Enter Patient Name',)
author = models.ForeignKey(
'auth.User',on_delete=models.CASCADE,
)
def __str__(self):
return self.drug_name
def get_absolute_url(self):
return reverse('drug_detail', args=[str(self.id)])
urls.py
from django.urls import path
from .views import (
drugListView,
drugDetailView,
drugCreateView,
drugDeleteView,
drugUpdateView,
)
urlpatterns = [
path('drug/<int:pk>/delete/',
drugDeleteView.as_view(), name='drug_delete'),
path('drug/new/', drugCreateView.as_view(), name='drug_new'),
path('drug/<int:pk>/', drugDetailView.as_view(), name='drug_detail'),
path('drug/<int:pk>/edit/',
drugUpdateView.as_view(), name='drug_edit'),
path('', drugListView.as_view(), name='home'),
]
views.py
from django.views.generic import ListView, DetailView
from django.views.generic.edit import (
CreateView, UpdateView, DeleteView
)
from django.urls import reverse_lazy
from .models import DrugInfo
class drugListView(ListView):
model = DrugInfo
template_name = 'home.html'
class drugDetailView(DetailView):
model = DrugInfo
template_name = 'drug_detail.html'
class drugCreateView(CreateView):
model = DrugInfo
template_name = 'drug_new.html'
fields = ['drug_name', 'patient_name', 'author']
class drugUpdateView(UpdateView): # new
model = DrugInfo
template_name = 'drug_edit.html'
fields = ['drug_name', 'patient_name']
class drugDeleteView(DeleteView): # new
model = DrugInfo
template_name = 'drug_delete.html'
success_url = reverse_lazy('home')
drug_edit.html
{% extends 'base.html' %}
{% block content %}
<h1>Edit Drug Information</h1>
<form action="" method="post">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Update">
</form>
{% endblock content %}
base.html
{% load static %}
<html>
<head>
<title>Script Tracker Title Base HTML</title>
<link href="https://fonts.googleapis.com/css?family=Tangerine" rel="stylesheet">
<link href="{% static 'css/base.css' %}" rel="stylesheet">
</head>
<body>
<div>
<header>
<div class="nav-left">
<h1>Script Tracker</h1>
</div>
<div class="nav-right">
+ Add New Drug
</div>
</header>
{% block content %}
{% endblock content %}
</div>
</body>
</html>
drug_detail.html
{% extends 'base.html' %}
{% block content %}
<div class="drug-entry">
<h2>{{ post.drug_name }}</h2>
<h2>{{ post.patient_name }}</h2>
</div>
<p>+ Edit Drug Information</p>
<p>+ Delete Drug</p>
{% endblock content %}
Summary
I'm very new to all this and so I apologize if I have not posted all the needed information. I know I'm close and I have something messed up with the pk stuff. http://127.0.0.1:8000/drug/12/edit/ works fine when I type in the browser. Any suggestions would be greatly appreciated.
In your template drug_detail.html you refer to the DrugInfo object as follows: post or drug. While in fact the drugDetailView never passes such variables into the context. A DetailView by default passes the instance as object or <lowercase_model_name> (druginfo here). If you want to set the name it uses you can set context_object_name on the class:
class drugDetailView(DetailView):
model = DrugInfo
template_name = 'drug_detail.html'
context_object_name = 'drug'
Now in the template drug_detail.html:
{% extends 'base.html' %}
{% block content %}
<div class="drug-entry">
<!-- Use `drug` instead of `post` now -->
<h2>{{ drug.drug_name }}</h2>
<h2>{{ drug.patient_name }}</h2>
</div>
<p>+ Edit Drug Information</p>
<p>+ Delete Drug</p>
{% endblock content %}
Related
I am trying to make a contact form, but I guess I'm doing it wrong.
When I access /contact and put name, email, content in each field and click a submit button, I got an error.
NoReverseMatch at /contact/ Reverse for 'contact_result' not found.
'contact_result' is not a valid view function or pattern name.
view.py
from django.urls import reverse_lazy
from django.views.generic import TemplateView
from django.views.generic.edit import FormView
from .forms import ContactForm
class ContactFormView(FormView):
template_name = 'contact/contact_form.html'
form_class = ContactForm
success_url = reverse_lazy('contact_result')
def form_valid(self, form):
form.send_email()
return super().form_valid(form)
class ContactResultView(TemplateView):
template_name = 'contact/contact_result.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['success'] = "completed"
return context
urls.py
from . import views
from .views import DbDetail,ContactFormView, ContactResultView
app_name = 'db'
urlpatterns = [
path('', views.DbList.as_view(), name='list'),
path('contact/', ContactFormView.as_view(), name='contact_form'),
path('contact/result/', ContactResultView.as_view(), name='contact_result'),
]
contact_form.html
{% block content %}
<div class="container">
<div class="row">
<div class="col-md-8">
<h1>inquily</h1>
<p>inquily form</p>
<form method="POST">{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="btn btn-primary">submit</button>
</form>
</div>
</div>
</div>
{% endblock %}
contact_result.html
{% block content %}
{{ success }}
{% endblock %}
I just mentioned the above settings in this question but still if more code is required then tell me I'll update my question with that information.
I am trying to make a website that sorts equipment based on their category and i am getting the reverse match error when i link the urls on the webpage. Please i need advice on how i can properly pull this off. Thanks in advance.
urls.py
from django.urls import path
from . import views
app_name = 'equipments_catalogue'
urlpatterns = [
path('equipment_list/', views.EquipmentListView.as_view(), name='equipment_list'),
path('equipment_categories/', views.EquipmentCategoryView.as_view(),
name='equipment_categories'),
path('equipment_by_category/<str:cats>/', views.EquipmentListByCategory,
name='equipment_by_category')
]
views.py
from django.shortcuts import render
from django.views.generic import ListView
from . import models
# Create your views here.
class EquipmentCategoryView(ListView):
model = models.Category
template_name = 'equipment_categories.html'
def EquipmentListByCategory(request, cats):
equipment_category = models.Equipment.objects.filter(category=cats)
return render(request, 'equipment_by_category.html', {'cats': cats , 'equipment_category':
equipment_category})
class EquipmentListView(ListView):
model = models.Equipment
template_name = 'equipment_list.html'
template
{% extends 'base.html' %}
{% load static %}
{% block title %}Home{% endblock %}
{% block content %}
<h1>Welcome to JPI Equipment Categories Page</h1>
{% for category in object_list %}
<a href="{% url 'equipments_catalogue:equipment_categories' equipment_by_category.category
%}">{{ category.name }}</a><br><br>
{% endfor %}
{% endblock %}
You're calling it wrong. The correct way to call it is {% url '<app_name>:<url_name>' %}
Your app name is equipments_catalogue, your url name is equipment_by_category, not equipment_categories, which is correct, and the argument you should be passing should be a string, something like category.name:
{% url 'equipments_catalogue:equipment_by_category' category.name %}
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.
i created a blog
this is my models.py configurations:
from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User
from django.core.urlresolvers import reverse
# Create your models here.
class PublishedManager(models.Manager):
def get_queryset(self):
return super(PublishedManager, self).get_queryset()\
.filter(status='published')
class post(models.Model):
STATUS_CHOICE=(
('draft','DRAFT'),
('published','Published'),
('admin','admin'),
)
title=models.CharField(max_length=250,null=True)
author=models.ForeignKey(User,related_name='blog_posts',null=True)
slug=models.SlugField(max_length=250,unique_for_date='publish',null=True)
body=models.TextField(default='')
publish=models.DateTimeField(default=timezone.now)
created = models.DateTimeField(auto_now_add=True,null=True)
updated =models.DateTimeField(auto_now=True)
status = models.CharField(max_length=10,
choices =STATUS_CHOICE,
default='draft')
objects = models.Manager()
published = PublishedManager()
class Meta:
ordering = ('-publish',)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('blog:post_detail',args=[self.publish.year,
self.publish.strftime('%m'),
self.publish.strftime('%dz'),
self.slug])
and this is my views.py:
from django.shortcuts import render
from .models import post
# Create your views here.
def post_list(request):
posts= post.published.all()
return render(request,'blog/post/list.html',{posts:posts})
def post_detail(request,year,month,day,post):
post=get_object_or_404(post,slug=post,
status = 'published',
publish__year=year,
publish__month=month,
publish__day=day)
return render(request,'blog/post/index.html',{'post':post})
and this is my base.html:
{%load staticfiles%}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>{% block title %}
<link rel="stylesheet" href={% static "/css/blog.css"%}>
{% endblock %}
</title>
</head>
<body>
<div id="content">
{% block content %}
{% endblock %}
</div>
<div id="sidebar">
<h2>my blog</h2>
<h3>this blog</h3>
</div>
</body>
</html>
and my list.html file:
{% extends "blog/base.html" %}
{% block title %}My blog{% endblock %}
{% block content %}
<h1>My Blog</h1>
{% for post in posts %}
<h2>
{{ post.title }}
</h2>
<p class="date">
Published {{ post.publish }} by {{ post.author }}
</p>
{{ post.body|truncatewords:30|linebreaks }}
{% endfor %}
{% endblock %}
and this is my urls.py (app folder)
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$',views.post_list,name = 'post_list'),
url(r'^(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d{2})/(?P<post>[-\W]+)/$',
views.post_detail,
name='post_detail'),
]
and this is my urls.py file of my project folder:
from django.conf.urls import url,include
from django.contrib import admin
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^blog/', include('myblog.urls',namespace='blog',app_name='blog')),
]
and i have added some post objects using admin user but when i tried to access the page the expected output according to the tutorial looks like this:
enter image description here
but instead my output was :
enter image description here
Firstly, the key in your context dictionary should be the string 'posts', not the variable posts, as #ABDUL pointed out in the comments.
return render(request,'blog/post/list.html',{'posts':posts})
Then you need to fix the NoReverseMatch error. In your get_absolute_url method, you have %dz. It should be '%d'. Remove the z.
def get_absolute_url(self):
return reverse('blog:post_detail',args=[self.publish.year,
self.publish.strftime('%m'),
self.publish.strftime('%d'),
self.slug])
I am trying a simple thing User clicks a question displayed. The link when clicked would take in the question id and pass it as an argument to display the relevant Choices. The user is asked to chose a Choice and then the next page would display how many people has voted for that Choice(including the user's current decision).
The Error I am getting is when I start the app using 127.0.0.1:8000/polls/ it displays the question. Then when I click the question the url becomes 127.0.0.1:8000/polls/3/ which is correct as 3 is the question id. So it is expected to show the Choices for the Question ID. But it is not showing.
The Error is:
NoReverseMatch at /polls/3/
Reverse for 'results' with arguments '()' and keyword arguments '{'q_id': 3, 'c_test': 'May Be'}' not found. 1 pattern(s) tried: ['polls/(?P<q_id>[0-9]+)/(?P<c_test>\\w+)/results/$']
Request Method: GET
Request URL: http://127.0.0.1:8000/polls/3/
Django Version: 1.10.3
Exception Type: NoReverseMatch
Exception Value:
Reverse for 'results' with arguments '()' and keyword arguments '{'q_id': 3, 'c_test': 'May Be'}' not found. 1 pattern(s) tried: ['polls/(?P<q_id>[0-9]+)/(?P<c_test>\\w+)/results/$']
Exception Location: /home/usr/.local/lib/python3.5/site-packages/django/urls/resolvers.py in _reverse_with_prefix, line 392
Python Executable: /usr/bin/python3.5
Python Version: 3.5.2
My code is:
views.py
class IndexView(generic.ListView):
template_name = "polls/index.html"
context_object_name = "latest_question_list"
model = Question
def get_queryset(self):
return Question.objects.filter(
pub_date__lte=timezone.now()
).order_by('-pub_date')[:5]
class DetailView(ListView):
model = Choice
context_object_name = "latest_choice_list"
template_name = "polls/detail.html"
def get_queryset(self):
print(self.args[0])
'''Return list of choices'''
return Choice.objects.filter(question_id=self.args[0])
# return Choice.objects.all()
def pollvote(request, q_id, c_test):
if c_test:
p = Choice.objects.filter(question_id=q_id).get(choice_test=c_test)
count = p.votes
count += 1
p.votes = count
p.save()
return HttpResponseRedirect('/polls/%s/%s/results/' % c_test, q_id)
detail.html (error says problem at the href line)
{% load staticfiles %}
<link rel="stylesheet" type="text/css" href="{% static 'polls/style.css' %}" />
{% if latest_choice_list %}
<p>Cast your Choice</p>
<ul>
{% for choice in latest_choice_list %}
<li>{{ choice.choice_test }}</li>
{% endfor %}
</ul>
{% else %}
<p>No choice are available.</p>
{% endif %}
results.html:
{% load staticfiles %}
<link rel="stylesheet" type="text/css" href="{% static 'polls/style.css' %}" />
{% if latest_choice_list %}
<p>Choices Made So Far</p>
<ul>
{% for choice in latest_choice_list %}
<li>{{ choice.choice_test }} - {{ choice.votes }} </li>
{% endfor %}
</ul>
{% else %}
<p>No choice are available.</p>
{% endif %}
urls.py
urlpatterns = [
url(r'^$', views.IndexView.as_view(), name='index'),
url(r'^([0-9]+)/$', views.DetailView.as_view(), name='detail'),
url(r'^(?P<q_id>[0-9]+)/(?P<c_test>\w+)/results/$', views.pollvote, name='results'),]
Why is the detail.html is throwing error? Why is it not taking the two keyword named arguement and passing it to the result?
Try this:
{{ choice.choice_test }}
Django will automatically assign the args in given order.
P.S.
I am assuming that Choice model has question_id and choice_test field.
If you have question_id as an integer field as a reference to any Question object then instead of doing this, you can use Foreign key field of django.medels . https://docs.djangoproject.com/en/1.10/topics/db/examples/many_to_one/