Im making a applikation in django and im totaly new to to language python and framework django.
My problem is i can't figure out how to get this url:
project/2/ticket/1
Im in project/2 and got an link in my template that links to project/2/ticket/1.
The error i get is NoReverseMatch at /project/1 and the code im using is:
url.py
urlpatterns = patterns('',
# Project urls below
url(r'^project/(?P<project_id>\d+)$', 'project_manager.views.project_list', name='project_list_with_ticket'),
url(r'^project/(?P<project_id>\d+)/ticket/(?P<ticket_id>\d+)$', 'project_manager.views.ticket_list', name='ticket_list'),
# Uncomment the next line to enable the admin:
url(r'^admin/', include(admin.site.urls)),
)
views.py
def ticket_list(request, ticket_id = None):
if ticket_id:
tickets = get_list_or_404(Ticket.objects.filter(id = ticket_id))
return render(request, 'tickets/details.html', {"tickets" : tickets })
else:
return render(request, 'projects/list.html', {'projects' : projects })
my template
{% for ticket in tickets %}
<div class="tickets">
{{ ticket }}
</div>
{% endfor %}
EDIT --
It says there is no ticket_list, but there are?
You are calling the ticket_list URL/View with one variable - ticket.id - when it requires two.
Your template:
{{ ticket }}
You are passing a ticket.id and it also requires a project.id as you can see in your URL:
url(r'^project/(?P<project_id>\d+)/ticket/(?P<ticket_id>\d+)$', 'project_manager.views.ticket_list', name='ticket_list'),
You need to change your template to pass both variables that you are asking for in the URL. You haven't posted how you get the project id, so my code will probably not work exactly as posted, but you need something like this:
{{ ticket }}
The order that the variables are passed need to align with the way that they are asked for in your URL. Since your URL asks for a project_id and then a ticket_id, make sure you pass them in your template in that order as outlined above.
Related
In my Django project, I have created a custom admin page for an app via the get_urls() method. I'd like to add a link to the app's main model index view that will take users to this custom page - however, I'm having some trouble creating this link element correctly and I don't seem to be able to piece together the right way to do it - I'm just left with a Reverse for 'export' not found. 'export' is not a valid view function or pattern name. error.
I've set up the admin for the app like so:
# my_project/observations/admin.py
from django.template.response import TemplateResponse
from django.urls import path
class ObservationAdmin(SimpleHistoryAdmin, SoftDeletionModelAdmin):
change_list_template = 'export_link.html'
def get_urls(self):
urls = super().get_urls()
custom_urls = [
path('export/', self.admin_site.admin_view(self.export_view), name='export')
]
return custom_urls + urls
def export_view(self, request):
context = dict(
self.admin_site.each_context(request),
)
return TemplateResponse(request, 'export.html', context)
and the two templates that are referenced:
# my_project/observations/templates/export.html
{% extends "admin/base_site.html" %}
{% block content %}
<div>
Some custom content
</div>
{% endblock %}
# my_project/observations/templates/export_link.html
{% extends 'admin/change_list.html' %}
{% block object-tools-items %}
<li>
Export
</li>
{{ block.super }}
{% endblock %}
Navigating directly to http://localhost:8000/admin/observations/observation/export/ works perfectly, I see the custom content page exactly as I want it... so the issue I'm striking is with the link template - I get the Reverse... error when I navigate to the model index page.
Perhaps the argument I'm passing to url is incorrect, or I need to register that URL elsewhere - but I don't quite know. The other examples of link elements like this that I've been able to find don't reference URLs created via the admin class' get_urls() method - so any guidance on this would be greatly appreciated.
Thanks very much, let me know if there's any other info that I can provide to help sort this out.
I think the problems is in missing namespace in your export_link.html template. Instead of:
Export
try:
Export
I have a html template on which multiple messages are posted and can be deleted using a 'delete' button that has been created. My code seeks to search for the id of the item to be deleted and delete it, redirecting to /deleteMessage and concatenating with the id number. I don't fully understand the process and have an error I cannot spot.
html form
<ul>
{% for g in all_items %}
<li> {{ g.content }}
<form action="/deleteMessage/{{g.id}}/"
style="display: inline;"
method="post">{% csrf_token %}
<input type="submit" value="Delete"/>
</form>
</li>
{% endfor %}
</ul>
views.py relevant code
def deleteMessage(request,GuestBookItem_id):
item_to_delete =GuestBookItem.objects.get(id=GuestBookItem_id)
item_to_delete.delete()
return HttpResponseRedirect('/worldguestbook/')
urls.py
urlpatterns = [
path('admin/', admin.site.urls),
path('worldguestbook/',worldguestbookView),
path('login/',loginView),
path('addMessage/',addMessage),
path('deleteMessage/',deleteMessage),
]
I imagine it is this line that is causing the error - an error in concatenation and not redirecting to the right path.
**<form action="/deleteMessage/{{g.id}}/"**
Error message:
Page not found (404)
Request Method: POST
Request URL: http://127.0.0.1:8000/deleteMessage/17/
Using the URLconf defined in mysite.urls, Django tried these URL patterns, in this order:
admin/
worldguestbook/
login/
addMessage/
deleteMessage/
The current path, deleteMessage/17/, didn't match any of these.
What I tried:
I tried, in views.py changing this to g.id (instead of GuestBookItems.id) to match with what is in the form, but that didn't work either.
item_to_delete =GuestBookItem.objects.get(id=g_id)
You need to capture GuestBookItem_id in the URL pattern:
path('deleteMessage/<int:GuestBookItem_id>/', deleteMessage),
Note that in Python, you would normally use guest_book_item_id as the variable name. Or since it's the primary key of a model instance, you could use pk. It would be a good idea to use get_object_or_404, so that you get a 404 page when the item does not exist.
You're already using a POST request, which is a good idea when you are changing or deleting objects. You should also check that it's a POST request in the view.
Finally, it's a good idea to reverse URLs instead of hardcoding them. First, you need to add names to your URL patterns, then you can use {% url %} in the template and reverse() or the redirect shortcut in the template.
Putting that together, you get:
<form action="{% url 'delete_message' g.id %}">
urlpatterns = [
path('admin/', admin.site.urls),
path('worldguestbook/', worldguestbookView, name="worldguestbook"),
path('login/', loginView, name="login"),
path('addMessage/', addMessage, name="add_message"),
path('deleteMessage/', deleteMessage, name="delete_message"),
]
path('deleteMessage/<int:pk>/', deleteMessage),
from django.shortcuts import get_object_or_404, redirect
def deleteMessage(request, pk):
if request.method == "POST"
item_to_delete = get_object_or_404(GuestBookItem, pk=pk)
item_to_delete.delete()
return redirect('worldguestbook')
I made this many times and it worked, but not this time.
I get this error when I try to use {% url path.to.view %} django's template tage:
AttributeError at /login/ 'str' object has no attribute 'regex'
urls.py (main)
urlpatterns= patterns('', (r'', include('authenticate.urls')), )
urls.py (my app)
urlpatterns= patterns('authenticate.views', url(r'^login/$','login'),)
login.html
{{ form }}
{% url authenticate.views.login %} < --- Error comes here
in the views:
return render_to_response('login.html',{'form':form},context_instance=RequestContext(request), )
Doesn't also work with:
{% url authenticate.views.login %}
{% url 'authenticate.views.login' %}
{% url "authenticate.views.login" %}
This is on django 1.4; what possibly I'm doing wrong, or what do I miss in that version of django?
Thanks in Advance!
Update:
I can also add that using reverse in my views doesn't work and gives me the same error above:
from django.core.urlresolvers import reverse
result = reverse('django.contrib.auth.views.password_reset')
HttpResponse(result)
Error:
AttributeError at /abc/ 'str' object has no attribute 'regex'
Check this
https://docs.djangoproject.com/en/1.4/topics/http/urls/
You can add a name to your URL to help the refer.
Also check how you are declaring the pattern. It should be done like this:
urlpatterns = patterns('',
url(r'^archive/(\d{4})/$', archive, name="full-archive"),
url(r'^archive-summary/(\d{4})/$', archive, {'summary': True}, "arch-summary"),
)
I got it :))
The problem wasn't in the url template tag, it was in another urls file that's been included in the main one; the problem doesn't show till my app. hits url template tage or django's reverse method, otherwise, django doesn't complain about any url!!
Django newbie here. Following the documentation, I am trying the following to get a link to the admin site from the homepage of the public site I'm building:
{% load admin_urls %}
<p>Go to the admin.</p>
I am getting the error:
NoReverseMatch at /
u'opts|admin_urlname' is not a registered namespace
I am including the URLs properly:
url(r'^admin/', include(admin.site.urls)),
My template loaders are in the right order.
I've tried a few different variations on this, and they all throw namespace errors.
Any ideas? Thanks!
After 30 minutes with Daniel Roseman / Django docs in one screen and my code in the other, I come up with this simple solution:
In your views.py, add the opts context with the _meta of the model (that includes the required app_label and model_name):
class YourModelDetailView(DetailView):
def get_context_data(self, **kwargs):
context = super(YourModelDetailView, self).get_context_data(**kwargs)
context["opts"] = YourModel._meta
return context
In your templates:
{% url opts|admin_urlname:'change' object.pk %}
Where change can be any action in the reverse admin urls documentation page.
While the above answers were helpful about the code I was calling, there is a much easier way. I'm using this instead:
{% url 'admin:index' %}
This works for custom admin views as well, like:
{% url 'admin:myapp_mymodel_<keyword>' object.id %}
Where keyword is from the named parameters listed here (i.e. add, change, delete).
You are almost certainly using the released 1.4 version, rather than the development version. As the documentation for that version shows, you need to use {% load url from future %} before you can use that syntax.
If I want to have django app called app1 which can make a user post note to someone's page and to his/her own page.
And if the user is logged in ,no need using username in the url, but the username parameter in url can be acts as parent in urlconf.
To make it clear:
urls.py
urlpatterns = patterns(''
#if registered user/anonymous user visit someone's page
url(r'^/foo/users/(?P<username>\w+)/app1/',include('app1.urls', namespace='myapp1')),
#if user is logged in in his own page
url(r'^app1/', include('app1.urls', namespace='myapp1')),
...
)
app1/urls.py
urlpatterns = patterns('',
# I expect this pattern receives the username parameter from above
url(r'^note/add/$', app1_views.add_note,
name='add_note'),
url(r'^note/add/$', app1_views.add_note,
{ 'username':None}, name='add_note_own'),
...
...
)
app1/views.py
def add_note(request, username=None):
...
...
First question:
Now for example john is logged in and on jack's notes page john want to post a note.
I want to be able to do something like this or near something like this:
template app1/notes.html
{% if request.user.is_authenticated %}
{%if in his/her own note page %}
add note Expected generated url: www.domain.com/app1/add
{%else}
add note Expected generated url: www.domain.com/foo/jack/app1/add
{%endif%}
{% endif %}
Is this possible?
Another thing,
if john wrote note in jack's page, and django gives the note id == 3,
so to show that note, only these urls are valid:
www.example.com/foo/jack/app1/3
www.example.com/foo/app1/3 (if jack logged in)
Second question:
what I want to achieve is reverse match can accept captured parameter up to to the
parent urlconf when include() is involved in url configuration.
Can this be done?
Or if you get what I mean and can provide simpler solution , please do so :)
sorry if this post is confusing, I am confused myself.
Thanks alot for the patience.
I'm using django 1.2.5
you need to pass an username, one example can be:
urlpatterns = patterns('',
# I expect this pattern receives the username parameter from above
url(r'^note/add/(?P<username>[^/]+)/$', app1_views.add_note, name='add_note'),
# username is an optional argument, so no need to pass it
url(r'^note/add/$', app1_views.add_note, name='add_note_own'),
)
and then in template:
{% if request.user.is_authenticated %}
{% if page.owner == request.user %}
add note
{% else %}
add note to {{ request.user.username }}
{% endif %}
{% endif %}