I have the following paths set up:
urlpatterns = [
path("", views.index, name="index"),
path('entry/<str:title>', views.entry, name='entry'),
]
my entry method is:
def entry(request,title):
entries = []
entry = util.get_entry(title)
if entry != None:
entries.append(entry)
return render(request, "encyclopedia/entry.html", {
"title": title,
"entries": entries,
})
and in my html we have:
{% block body %}
<h1>All Pages</h1>
<ul>
{% for entry in entries %}
<li>
a href = "{% url 'entry' title=entry %}" >{{ entry }}</a>
</li>
{% endfor %}
</ul>
{% endblock %}
two questions:
Is this the right way to pass parameters with a link?
What would I need to change to pass multiple parameters?
Is this the right way to pass parameters with a link?
Yes, by using the {% url … %} template tag [Django-doc] you calculate the path for a given view name and parameter(s).
There is however a small error in the HTML: you need to open the <a> tag, and furthermore not use spaces between the equal sign (=):
{{ entry }}
What would I need to change to pass multiple parameters?
You define extra parameters in the view, for example:
urlpatterns = [
# …,
path('entry/<str:title>/<str:theme>/', views.entry, name='entry'),
]
and you specify values for the two parameters:
{{ entry }}
the view then takes three parameters:
def entry(request, title, theme):
# …
Related
I am doing CS50 Project 2 and need to make a webpage that takes in the id through the url and retrieves all of the information about that particular item from the database to display on the webpage.
def listing(request, id):
id = Listings.objects.get(id=2)
return render(request, "auctions/listing.html",{
"listings": Listings.objects.all()
})
This is my current code. I am trying to get the id that is in the url parameter through the variable, and I want the listings variable to only get the objects for that item, but I am not exactly sure how to do that.
urls.py
from django.urls import path
from .models import User, Listings
from .forms import ListingsForm
from . import views
urlpatterns = [
path("", views.index, name="index"),
path("login", views.login_view, name="login"),
path("logout", views.logout_view, name="logout"),
path("create", views.create, name="create"),
path("watchlist", views.watchlist, name="watchlist"),
path("categories", views.categories, name = "categories"),
path("listings/<int:id>/", views.listing, name = "listing"),
path("register", views.register, name="register")
]
listing.html
{% extends "auctions/layout.html" %}
{% block body %}
{{% for listing in listings %}
<img src ="{{ listing.image }}" style = "height: 10%; width: 10%;">
<h4 class = "text">{{ listing.title }}</h4>
<h6>Description: {{ listing.description }}</h6>
<h6>Category: {{ listing.category }}</h6>
<h6>Price: ${{ listing.bid }}</h6>
{% endfor %}
{% endblock %}
I know that I will have to change the listing.html once I have figured out how to get the id to display only the objects for that id, but for the time being this is my listing.html.
I'm making a lot of assumptions here, so apologies, but I think the page not found error and your original question are related, and I think it all comes down to making two different views, two different url paths, and two different templates. One view/path/template for all listings (plural), and another view/path/template for the individual listing (singular).
First the urls you will need:
path("listings/", views.listings, name = "listings"),
path("listing/<int:id>/", views.listing, name = "listing"),
What you already have seems like it would belong to the listings view/path/template, with some modifications. The listings view will not have an id, since it will display all the listings (note that I changed all these to listings as opposed to listing so I don't confuse this with the view that will take care of the single listing of a particular listing item:
def listings(request):
return render(request, "auctions/listings.html",{
"listings": Listings.objects.all()
})
This view can go with your listings template (note that I changed the name from listing.html to listings.html, since listing.html will take care of the particular listing, while listings.html will list all listings). Also note the <a href="{% url 'listing' listing.id %}"> part which is the the magical part where the url will be created with the particular listing's id (note that the name of the view goes after the url word, and that the id does not have quotes - it will be the parameter added to the generated url):
{% extends "auctions/layout.html" %}
{% block body %}
{{% for listing in listings %}
<img src ="{{ listing.image }}" style = "height: 10%; width: 10%;">
<h4 class = "text">{{ listing.title }}</h4>
<h6>Description: {{ listing.description }}</h6>
<h6>Category: {{ listing.category }}</h6>
<h6>Price: ${{ listing.bid }}</h6>
link to this particular listing's page
{% endfor %}
{% endblock %}
Now to the particular listing's detail page, where the above generated link will take the user to.
def listing(request, id):
listing = Listings.objects.get(id=id)
return render(request, "auctions/listing.html",{
"listing": listing
})
Next you have to create a template called listing.html where you can show all the details of the particular listing.
CS50 Web Programming course is fantastic, and very difficult. What helped me a lot was reading the notes, and also stopping the video and writing the code he demonstrates. All the answers are there. Just a suggestion; everyone learns differently. Good luck!
I'm trying to write the controller to search for articles. But the search does not find anything and a template appears that is not specified in the views.py.
# views.py
class SearchView(ListView):
template_name = 'search_view.html'
def get_queryset(self):
query = self.request.GET.get('q')
object_list = Article.objects.filter(Q(title__icontains=query))
return object_list
# urls.py
urlpatterns = [
path('', ArticlesList.as_view(), name='list_view'),
path('<tag>/', ArticlesByTagsList.as_view(), name='articles_by_tags'),
path('articles/<slug:slug>', ArticleDetail.as_view(), name='detail_view'),
path('articles/create/', ArticleCreate.as_view(), name='create_view'),
path('articles/<slug:slug>/', ArticleUpdate.as_view(), name='update_view'),
path('articles/<slug:slug>/delete/', ArticleDelete.as_view(), name='delete_view'),
path('search/', SearchView.as_view(), name='search_view'),
]
#search_view.html
{% extends 'layout/basic.html' %}
{% block content %}
{{ object_list }}
{% endblock %}
The form looks like this
<form action="{% url 'articles:search_view' %}" method="get">
<input type="text" name="q" placeholder="Search...">
</form>
What am I doing wrong?
You should enumerate over the objects, so:
{% extends 'layout/basic.html' %}
{% block content %}
{% for object in object_list %}
{{ object.title }}
{% endfor %}
{% endblock %}
You should also specify the search/ path before the <tag>/ path, since Django always takes the item that first matches, and if you write search/ then it would first match with the <tag>/ and thus not fire the SearchView.
The urlpatterns thus should look like:
urlpatterns = [
# ↓ first specify the search/ path
path('search/', SearchView.as_view(), name='search_view'),
path('<tag>/', ArticlesByTagsList.as_view(), name='articles_by_tags'),
]
an effect of this, is that you can not use search as a tag. If you should be able to visit the articles_by_tags with search as tag, you should define non-overlapping patterns, so:
urlpatterns = [
path('search/', SearchView.as_view(), name='search_view'),
path('tag/<tag>/', ArticlesByTagsList.as_view(), name='articles_by_tags'),
]
I am trying to display filtered objects in my django template however for some reason I don't know django does not display them.
I have a similar views function and template which does indeed display but this particular function does not.
Here are my urls.py, html template and views.py files:
The views.py function responsible for the url:
def game_category_list(request, slug):
template = 'game_category_list.html'
category = get_object_or_404(gameIdentifier, game_choice=slug)
post = gameIdentifier.objects.filter(game_choice=category)
context = {
'category':category,
'post':post,
}
return render(request, template, context)
Url.py (which contains another url called and this does display all the posts associated with the slug.
urlpatterns = [
path('', views.index, name='index'),
path('categories/<slug:slug>', views.game_category_list, name='game_category_list'),
path('<slug:slug>/', views.category_detail, name='game_category'),
]
Here is the html file for the game_category_list function:
{% extends 'base_layout.html' %}
{% block content %}
<div class='gamecategories'>
{% for game in post %}
<div class='gamecategoriesdisplay'>
<h1>{{game.game_name}}</h1>
</div>
{% endfor %}
</div>
{% endblock %}
I don't know why this doesn't work. Any help would be appreciated.
I had a similar problem. it was due to filter not matching capital letters from my categories, you have to make sure your categories are added in lowecase so it match with the slugs in the url. Once you have changed it, you have to reassign the category or it will keep showing the older one
I have three pages - homepage, http://127.0.0.1:8000/, displaying one paragraph sentence and two links in the header. and list of pizzas, http://127.0.0.1:8000/pizzas . Now i was trying to add links for each pizza on http://127.0.0.1:8000/pizzas page, so that one could click on them and see what toppings were available. I'm probably stuck because of my decision to use paths instead of url() for mapping urls, which the book i'm following uses.
Error : NoReverseMatch at /pizzas.
Reverse for 'pizza_w_toppings' not found. 'pizza_w_toppings' is not a valid view function or pattern name.
pizzas.html -
{% extends "pizzeria_app/base.html" %}
{% block content %}
<h1> Available Pizzas : </h1>
<ul>
{% for pizza in pizzas %}
<li> <a href = {% url 'pizza_w_toppings' %}> {{pizza}}</a><li>
{% empty %}
<p> We're outta Pizzas. next time bro! <p>
{% endfor %}
</ul>
{% endblock content %}
app/urls.py :
urlpatterns = [
#homepage
path('', views.index),
#show available pizzas
path('pizzas', views.pizzas),
path('pizzas/<int:pizza_id>', views.pizza_w_toppings, name="pizza_w_toppings")
Views:
I'm new to StackOverflow and can't figure out how to add my views.py. i attached a picture, sorry
views.py screenshot
Your url tag should be {% url 'pizza_w_toppings' pizza.id %}. If you check the documentation, you'll see all possible variations of url tag.
For example, suppose you have a view, app_views.client, whose URLconf
takes a client ID (here, client() is a method inside the views file
app_views.py). The URLconf line might look like this:
path('client/<int:id>/', app_views.client, name='app-views-client')
If this app’s URLconf is included into the project’s URLconf under a
path such as this:
path('clients/', include('project_name.app_name.urls'))
…then, in a template, you can create a link to this view like this:
{% url 'app-views-client' client.id %}
The template tag will output the string /clients/client/123/.
If you use namespaces, make sure to include namespace in your url tags like this:
{% url 'your-namespace:app-views-client' client.id %}
I have a link to note detail page (s_note) in the user page (username). So as long as I have no entries(notes) in the database for the user the user page renders fine, but as soon as there is a valid note the render fails with the above error and points to ln:6 of user.html.
my urls.py
from django.conf.urls import url
from notes.models import User, Note
from . import views
app_name = 'notes'
urlpatterns = [
url(r'^$', views.index, name='u_index'),
my url
url(r'^signup/$', views.signup, name='u_signup'),
url(r'^(?P<user_id>[\w\-]+)/$', views.user, name='username'),
url(r'^(?P<user_name>[\w\-]+)/(?P<note_t>[\w\-]+)/$', views.note, name='s_note'),
url(r'^(?P<user_name>[\w\-]+)/(?P<note_t>[\w\-]+)/$', views.note, name='s_note')
]
my views
def note(request, user_name, note_t):
nt = Note.objects.get(note_title=note_t)
return render (request, 'notes/detail.html', {'note': nt})
my users.html
<h2>Hi! {{ user.user_n }} Your notes are here.</h2>
{% if allnotes %}
<ul>
{% for note in allnotes %}
<li>{{ note.note_title }}</li>
{% endfor %}
</ul>
{% else %}
<p>You have no notes yet!</p>
{% endif %}
<form method="post" action"">
<table>
{% csrf_token %}
{{ NForm }}
</table>
<input type="submit" value="Create">
</form>
Your url doesn't match for underscores or spaces which your keyword currently contains.
url(r'^(?P<user_name>[\w\-]+)/(?P<note_t>[\w\-]+)/$', views.note, name='s_note'),
should be
url(r'^(?P<user_name>[\w\-]+)/(?P<note_t>[\w\-\_\s]+)/$', views.note, name='s_note'),
although this isn't much of a solution since most spaces would turn into %20's, you should try to remove any spaces from your keywords and update your regex accordingly.
It was a namespacing problem as #Alasdair observed, it sorted with the edit -
'{% url 'notes:s_note'...%}'
in the template.