NoReverseMatch found - python

I am using django 1.7 & python 3.4
I am trying to implement follow and unfollow a user into my website but i am stuck.
urls.py
url(r'^user/', include('myuserprofile.urls'),),
myuserprofile.urls.py
urlpatterns = patterns('',
url(r'^(?P<slug>[^/]+)/$', 'myuserprofile.views.profile', name='profile'),
url(r'^(?P<slug>[^/]+)/follow/$', 'myuserprofile.views.follow', name='follow'),
url(r'^(?P<slug>[^/]+)/unfollow/$', 'myuserprofile.views.unfollow', name='unfollow'),
views.py
#login_required
def follow(request):
myuser = request.user.id
if request.method == 'POST':
to_user = MyUser.objects.get(id=request.POST['to_user'])
rel, created = Relationship.objects.get_or_create(
from_user=myuser.myuserprofile,
to_user=to_user,
defaults={'status': 'following'}
)
else:
return HttpResponseRedirect(reverse('/'))
if not created:
rel.status = 'following'
rel.save()
and the template portion is like this:
<form action="{% if relationship.status == 'F' %}{% url 'unfollow' %}{% else %}{% url 'follow' %}{% endif %}" method="POST">
Reverse for 'follow' with arguments '()' and keyword arguments '{}' not found. 1 pattern(s) tried: ['user/(?P[^/]+)/follow/$']

You should add the username of the user to follow/unfollow:
{% url 'follow' user_to_follow.username %}
Change the urls.py to:
urlpatterns = patterns('myuserprofile.views',
url(r'^(?P<username>[^/]+)/$', 'profile', name='profile'),
url(r'^(?P<username>[^/]+)/follow/$', 'follow', name='follow'),
url(r'^(?P<username>[^/]+)/unfollow/$', 'unfollow', name='unfollow'),
)
And the signature of the view should accept the username argument:
#login_required
def follow(request, username):
myuser = request.user.id
if request.method == 'POST':
to_user = MyUser.objects.get(username=username)
...

You need to use namespaced URL.
In your case the URL unfollow should be referenced as <app_name>:unfollow.

URL namespaces allow you to uniquely reverse named URL patterns even
if different applications use the same URL names. It’s a good practice
for third-party apps to always use namespaced URLs (as we did in the
tutorial). Similarly, it also allows you to reverse URLs if multiple
instances of an application are deployed. In other words, since
multiple instances of a single application will share named URLs,
namespaces provide a way to tell these named URLs apart
have a look on this Here
you have to use URL namespaces
here is my
polls/urls.py
from django.conf.urls import patterns, url
from . import views
urlpatterns = patterns('',
url(r'^$', views.IndexView.as_view(), name='index'),
url(r'^(?P<pk>\d+)/$', views.DetailView.as_view(), name='detail'),
...
)
so we have use like
{% url 'polls:index' %}

You were missing the slug in your template.
<form action="{% if relationship.status == 'F' %}{% url 'unfollow' %}{% else %}{% url 'follow' %}{% endif %}" method="POST">
It should be
<form action="{% if relationship.status == 'F' %}{% url 'unfollow' user.username %}{% else %}{% url 'follow' user.username %}{% endif %}" method="POST">

Related

How do I fix a reverse error in Django when redirecting?

I am currently working on a website where you can create a shopping list. I am trying to insert items into the shoplist. So things like banana, cake, etc would go into shoplist. I got everything to work. When I create the item, it goes inside the database but when I try to redirect back to the website where I pressed create item, it shows the error
Reverse for 'detail' with keyword arguments '{'pk': 1}' not found. 1 pattern(s) tried: ['shoplist/(?P<item_id>[0-9]+)/$']
Also, when I try to enter my details page, it shows the error
Reverse for 'createitem' with arguments '('',)' not found. 1 pattern(s) tried: ['shoplist/(?P<item_id>[0-9]+)/createitem/$']
I think I did something wrong when making my paths or doing something wrong syntax wise. Nothing I found on the internet is fixing it. Is there a way to fix this problem? Thank you very much!
views.py
def createitem(request, item_id):
if request.method == 'GET':
return render(request, 'shoplist/createitem.html', {'form':ItemForm(), 'id':item_id})
else:
form = ItemForm(request.POST)
itemlist = form.save(commit=False)
itemlist.shoplist = Shoplist.objects.filter(user=request.user, pk=item_id).first()
itemlist.user = request.user
itemlist.save()
return redirect('detail', pk=item_id)
urls.py
from django.contrib import admin
from django.urls import path
from shoplist import views
urlpatterns = [
path('admin/', admin.site.urls),
path('', views.home, name='home'),
#authentication
path('signup/', views.usersignup, name='usersignup'),
path('logout/', views.userlogout, name='userlogout'),
path('login/', views.userlogin, name='userlogin'),
path('create/', views.createlist, name='createlist'),
path('shoplist/', views.currentshoplist, name='currentshoplist'),
path('shoplist/<int:item_id>/', views.detail, name='detail'),
path('shoplist/<int:item_id>/createitem/', views.createitem, name='createitem'),
]
detail.html
{% extends 'shoplist/base.html' %}
{% block content %}
<h2>{{ error }}</h2>
<h1>{{ shopitems }}</h1>
{% for i in item %}
{{i.item}}
{% endfor %}
<form action="{% url 'createitem' item_id %}" method="POST">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Create Item</button>
</form>
{% endblock %}
You want to redirect to the 'detail' view and the arg required for it is item_id as an int. I think you want redirect('detail', item_id=item_id). However, you probably want to get the created pk from the form... Maybe form.instance.pk? So redirect('detail', item_id=form.instance.pk). It's not clear if that form is for saving the same object type as you're viewing with the 'detail' view.
For the {% url %}, I don't think you can use anything but keyword args. So, {% url 'createitem' item_id=item_id %} if you put item_id into the template context.

Django ERROR with tmeplate rendering. Reverse for 'login' not found. 'login' is not a valid view function or pattern name

Im new to Django (also to stackoverflow too) and im trying to make simple accounts system.
When im "sign out" button to main page im getting this error
Reverse for 'logout' not found. 'logout' is not a valid view function or pattern name.
account/views.py
def signout_view(request):
if request.method == 'POST':
logout(request)
return redirect('/')
account/urls.py
app_name = 'account'
urlpatterns = [
path('signup/', views.signup_view, name='signup'),
path('signin/', views.signin_view, name='signin'),
path('signout/', views.signout_view, name='signout'),
]
home/templates/home/wrapper.html
<form class="logout-link" action="{% url 'account:logout' %}" method="post">
{% csrf_token %}
<button type="submit">Sign out</button>
</form>
anyone can help with fixing this problem?
reverse function gets the name stated at the end of the path funtion in urls.py and retrieves its url
path('signup/', views.signup_view, name='signup'),
here the name is 'signup' and reverse('signup') will return a 'signup/'. Jinja2's {% url %} tag just calls reverse in django
so to make thing work in your code
just do
<form class="logout-link" action="{% url 'account:signout' %}" method="post">
{% csrf_token %}
<button type="submit">Sign out</button>
</form>

Django authentication system

i'm using the django built in authentication system and in my login template i have this code :
login.html:
{% block title %}Login{% endblock %}
{% block content %}
<h2>Login</h2>
{% if user.is_authenticated%}
you are already logged in
{% else %}
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Login</button>
</form>
{% endif %}
{% endblock %}
but what i really want to do is to redirect the user to the home page if he tries to access login page while already logged in, but i am new to django so i don't know how to do that.
For django>=1.11 you can set redirect_authenticated_user parameter to True in its url in url_patterns to do the redirect, like this:
from django.contrib.auth import views as auth_views
urlpatterns = [
url(r'^login/', auth_views.LoginView.as_view(redirect_authenticated_user=True), name='login'),
]
read the document for more information.
and also set LOGIN_REDIRECT_URL in your setting file to your index url or its name:
LOGIN_REDIRECT_URL = '/index/'
In your `settings.py' add this:
LOGIN_REDIRECT_URL = 'index'
if the url name of your index is 'index', else put the correct url name
You can do it in your views.py file.
def login(request):
if request.method =="get":
if request.user.is_authenticated:
return render(// youre code)

Django Error passing URL argument from Template to View: NoReverseMatch Reverse not found. 1 pattern(s) tried

I am trying to pass configure a URL like so:
/details/12345
Template HTML:
<div class="row">
{% if article_list %}
{% for article in article_list %}
<div>
<h2>{{ article.title }}</h2>
<p>{{ article.body }}</p>
<p><a class="btn btn-default" href="{% url 'details' article.id %}" role="button">View details »</a></p>
</div><!--/.col-xs-6.col-lg-4-->
{% endfor %}
{% endif %}
</div><!--/row-->
urls.py (full):
from django.conf import settings
from django.conf.urls import include, url
from django.conf.urls.static import static
from django.contrib import admin
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^$', 'news_readr.views.home', name='home'),
url(r'^details/(?P<article_id>\d+)/$', 'news_readr.views.details', name='details'),
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
if settings.DEBUG:
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
views.py:
from django.shortcuts import render
from .models import Article
# Create your views here.
def home(request):
title = "Home"
article_list = Article.objects.all()
for article in article_list:
print(article.id)
context = {
"title": title,
"article_list": article_list,
}
return render(request, "home.html", context)
def details(request, article_id = "1"):
article = Article.objects.get(id=article_id)
return render(request, "details.html", {'article': article})
I am getting an error that says:
NoReverseMatch at /
Reverse for 'details' with arguments '()' and keyword arguments '{}'
not found. 1 pattern(s) tried: ['details/(?P<article_id>\\d+)/$']
I'm one week old at Django, and I think there's something wrong with my URL Named Group config. Please help! TIA!
Update: If I remove the URL config and change it back to:
url(r'^details/$', 'news_readr.views.details', name='details'),
The error changes to:
Reverse for 'details' with arguments '(1,)' and keyword arguments '{}'
not found. 1 pattern(s) tried: ['details/$']
So it seems to be picking up the argument that is passed 1 in this case. So this seems to be an issue with the regular expression. I tried the expression out at Pythex, but even there, the expression doesn't seem to be matching anything.
For the url pattern
url(r'^details/(?P<article_id>\d+)/$', 'news_readr.views.details', name='details'),
The correct way to use the tag is
{% url 'details' article.id %}
This because the details url pattern has a group article_id, so you have to pass this to the tag.
If you have the above url pattern, and {{ article.id}} displays correctly in the template, then the above template tag should not give the error Reverse for 'details' with arguments '()'. That suggests you have not updated the code, or you have not restarted the server after changing code.
If you change the url pattern to
url(r'^details/$', 'news_readr.views.details', name='details')
then you need to remove the article.id from the url tag.
{% url 'details' %}
I guess your pattern is wrong.( not an expert of regex ).
Try this
url(r'^details/((?P<article_id>[0-9]+)/$', 'news_readr.views.details', name='details'),

NoReverseMatch in Django (url ploblem)

I'm a beginner of Django
I want to set my url with database field_name instead of use primary key from Django tutorial. This is my code.
*mysite*
**dwru/urls.py**
urlpatterns = [
url(r'^$', include('product.urls', namespace="product")),
]
*myapp*
**product/urls.py**
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^(?P<name_catalog>[-_\w]+)/$', views.product_list_from_index, name='catalog'),
]
**product/views.py**
def product_list_from_index(request, name_catalog):
catalog = get_object_or_404(Catalog, name_catalog=name_catalog)
context = {
'catalog': catalog
}
return render(request,'product/product_list.html', context)
**product/models.py**
class Catalog(models.Model):
name_catalog = models.CharField(max_length=45)
product = models.ManyToManyField(Product)
**template/product/index.html**
{% for catalog in catalog_list %}
<h1><a href="{% url 'product:catalog' catalog.name_catalog %}">{{ catalog.name_catalog }}</h1>
{% endfor %}
Then I add Catalog field with "TestCa01" then it shown an error
NoReverseMatch at /
Reverse for 'catalog' with arguments '(u'TestCa01',)' and keyword arguments '{}' not found. 1 pattern(s) tried: [u'$(?P<name_catalog>[-_\\w]+)/$']
it kind of some problem with this line in template
{% url 'product:catalog' catalog.name_catalog %}
any Idea?
The $ in your first url pattern might be the issue. The dollar sign indicates that it's the the end of the pattern, so it would never bother to include/check the product urls. Is the index url working?

Categories