Using array elements as relative URLs in a django template - python

I am totally new to django, and have been struggling with the following issue for a while.
I am sending a sorted list of lists to a template from views.py to a template, in which each sublist (containing two elements) should be displayed. I would like the first element to be a link, in such a way that the String content should be the relative URL to be displayed.
So I used the following syntax:
{{user.0}}
but it gives me the following error:
TemplateSyntaxError at /app/best_travelled/
Could not parse the remainder: '{{user.0}}' from '{{user.0}}'
Please find below the relevant code snippets:
views.py:
def best_travelled(request):
trips = Trip.objects.all()
user_trips={}
for trip in trips:
user_trips[trip.owner] = user_trips.get(trip.owner,0)+1
user_list = []
for key, value in sorted(user_trips.items(), key = itemgetter(1), reverse = True):
user_list.append([key, value])
context_dict = {'user_list':user_list}
return render(request,'best_travelled.html',context_dict)
Template:
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Most Recent Trips - Travelmate</title>
</head>
<body>
<h1>Best-Travelled</h1>
<div>
{% if user_list %}
<ol>
{% for user in user_list %}
{{user.0}}
<li>{{user.0}}, Number of trips: {{user.1}}</li>
{% endfor %}
</ol>
{% else %} There are no travellers yet! This is your chance to become the very first one! <br /> {% endif %}
Add a New Trip
</div>
<div>
<ul>
<li>Login</li>
</ul>
</div>
</body>
</html>
And for the profiles:
views.py
#login_required
def view_profile(request,username):
user = get_object_or_404(User, username=username)
trips = Trip.objects.filter(owner=request.user)
context_dict = {'user':user, 'trips':trips }
return render(request,'view_profile.html',context_dict)
app/urls.py
urlpatterns = [
url(r'^$', views.home, name='home'),
url(r'^about/$', views.about, name='about'),
url(r'^contact/$', views.contact, name='contact'),
url(r'^pop_trips/$', views.pop_trips, name='pop_trips'),
url(r'^recent_trips/$', views.recent_trips, name='recent_trips'),
url(r'^best_travelled/$', views.best_travelled, name='best_travelled'),
url(r'^most_active_travellers/$', views.contact, name='most_active_travellers'),
url(r'^passport/$', views.passport, name='passport'),
url(r'^add_trip/$', views.add_trip, name='add_trip'),
url(r'^settings/$', views.settings, name='settings'),
url(r'^my_trips/$', views.my_trips, name='my_trips'),
url(r'^(?P<username>[\w\-]+)/$', views.view_profile, name='view_profile')
]
project/urls.py
urlpatterns = [
url(r'^$', app_views.home, name='home'),
url(r'^admin/', admin.site.urls),
url(r'^login/$', auth_views.login, name='login'),
url(r'^logout/$',auth_views.logout,name='logout'),
url(r'^oauth/',include('social_django.urls',namespace='social')),
url(r'^accounts/register/$', MyRegistrationView.as_view(), name='registration_register'),
url(r'^accounts/',include('registration.backends.simple.urls')),
url(r'^app/', include('app.urls')),
url(r'^(?P<username>[\w\-]+)/$', app_views.view_profile, name='view_profile'),
]+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Thanks heaps to anyone who can help!

You don't have to use {{ for variables inside {%. Just write:
{{user.0}}

It should be:
{{user.0}}
Considering you have:
url(r'my-url/(?P<arg_1>[0-9a-f-]+)/(?P<arg_2>[a-f-]+)/$', MyClassView.as_view(), name="url_name"),
Where:
url_name is the name of your url
arg_1 and arg_1 are your arguments for your url(if there is the case, if not stays without them).
like: {{user.0}}
Side-note:
Once you are {% here %} all the context pushed is available without any extra {{ and }}

Related

Can't display object properties when retrieving an Item List

I am trying to display the watchlisted items of the logged in user. I am able to display a list but the item details such as title, price etc. don't show up.
models.py:
class Watchlist(models.Model):
user = models.ForeignKey(User, on_delete = models.CASCADE, name = "user")
item = models.ForeignKey(AuctionItem, on_delete = models.CASCADE, name = "item")
def __str__(self):
return f"Username: {self.user} / {self.item} "
views.py:
#login_required
def watchlist(request,user):
user = request.user
item_list = Watchlist.objects.filter(user_id=user)
return render(request, "auctions/watchlist.html",{
"item_list" : item_list
})
watchlist.html:
{% extends "auctions/layout.html" %}
{% block body %}
{% for item in item_list %}
<div class = "frame">
{% if item.image %}
<img src="{{item.image}}" style= "width: 30vw;">
{% endif %}
<h4>{{item.title}}</h4>
<div id="text"><strong>Price:</strong> ${{item.price}}</div>
<div id="text"><strong>Description:</strong> {{item.description}}</div>
<div id="text"><strong>Category:</strong> {{item.category}}</div><br>
<div id="date">Created {{item.date}}</div>
</div>
{% endfor %}
{% endblock %}
urls.py:
urlpatterns = [
path("", views.index, name="index"),
path("login", views.login_view, name="login"),
path("logout", views.logout_view, name="logout"),
path("register", views.register, name="register"),
path("create", views.create_listing, name="create"),
path("listing/<int:listing_id>", views.listing, name = "listing"),
path("<str:user>/watchlist", views.watchlist, name= "watchlist")
]
and here is what I'm getting as a result:
In view:
item_list = AuctionItem.objects.filter(watchlist__user=user)
The template stays untouched.
Or only in template in forloop it should be {{item.item.price}} because item alone is Watchlist object.

ValueError at /post/politics Field 'id' expected a number but got 'politics'

I have a template posts.html
{% extends 'base2.html' %}
{% block posts %}
<div class="row">
<div class="leftcolumn">
<div class="cardpost">
<h1>{{posts.title}}</h1>
<h5>{{posts.created_at}}</h5>
<div class="fs-4">{{posts.body | safe}}</div>
</div>
</div>
</div>
{% endblock %}
posts.html extends base2.html, because I want the posts.html to have nav bar functionality
<nav id="navbar" class="navbar">
<ul>
<li>About</li>
<li>Guest Posting</li>
<li class="dropdown"><span>Categories</span> <i class="bi bi-chevron-down dropdown-indicator"></i>
<ul>
<li>Tech</li>
<li>Bizconomics</li>
<li>Politics</li>
<li>Religion</li>
<li>Sports</li>
</ul>
</li>
<li>Contact</li>
</ul>
above is a section of the nav bar which is on base2.html, and also on the index.html. It works perfectly in the index.html. But when the user is on the posts.html-> path('post/str:pk', views.post, name='post') and they click politics category for instance, I get this error:
ValueError at /post/politics
Field 'id' expected a number but got 'politics'.
Here are my url routes
path('', views.index, name='index'),
path('post/<str:pk>', views.post, name='post'),
path('politicalpost/<str:pk>', views.politicalpost, name='politicalpost'),
path('bizconomicspost/<str:pk>', views.bizconomicspost, name='bizconomicspost'),
path('techpost/<str:pk>', views.techpost, name='techpost'),
path('sportspost/<str:pk>', views.sportspost, name='sportspost'),
path('religionpost/<str:pk>', views.religionpost, name='religionpost'),
path('subscribe', views.subscribe, name ='subscribe'),
path('contactform', views.contactform, name='contactform'),
path('about', views.about, name='about'),
path('guestposting', views.guestposting, name='guestposting'),
path('bizconomics', views.bizconomics, name='bizconomics'),
#These are the caregory urls
path('tech', views.tech, name='tech'),
path('sports', views.sports, name='sports'),
path('politics', views.politics, name='politics'),
path('religion', views.religion, name='religion'),
path('culture', views.culture, name='culture'),
path('culturepost/<str:pk>', views.culturepost, name='culturepost'),
So how can I make it possible such that when a user clicks on the politics category, they are redirected from the posts.html to the politics page->path('politics', views.politics, name='politics'),
My views.py
def index(request):
politics = Politics.objects.all().order_by('-created_at')
posts = Post.objects.all().order_by('-created_at')
trendingposts = Trending.objects.all().order_by('-created_at')
religions = Religion.objects.all().order_by('-created_at')
sliders = Heroslider.objects.all()
return render(request,
'index.html',
{'politics':politics, 'posts':posts,'trendingposts':trendingposts,'religions':religions, 'sliders':sliders})
def politics(request):
politics = Politics.objects.all()
return render(request, 'Politics/politics.html', {'politics':politics})
def post(request, pk):
posts = Post.objects.get(id=pk)
return render(request, 'posts.html', {'posts':posts})
Please try changing it:
<li>Politics</li>
With:
<li>Politics</li>

Keep getting NoReverseMatch error in Django project

I am trying to do a update function for this form. The template page displays properly, but once i click submit button, i keep getting the NoReverseMatch error: Reverse for 'update_page' with keyword arguments '{'title': ''}' not found. 1 pattern(s) tried: ['wiki/(?P[^/]+)/update$']
The project does not have models, as per assignment. The db is basically a folder in the same directory. And the files in this folder are being managed through the list_entries(), save_entry() and get_entry() functions in the util.py.
urls:
app_name = "entries"
urlpatterns = [
path("", views.index, name="index"),
path("newpage", views.newpage, name="newpage"),
path("<str:title>", views.open_page, name="open_page"),
path("search/", views.search, name="search_query"),
path("<str:title>/update", views.update_page, name="update_page"),
path("random/", views.random_page, name="random_page"),
path("<str:title>/deleted", views.del_page, name="del_page")
]
My views code:
def update_page(request, title):
entered_content = util.get_entry(title)
form_dict = {'form_title': title, 'form_content': entered_content}
if request.method == "POST":
form = NewPageForm(request.POST or None, initial=form_dict)
if form.is_valid():
title = form.cleaned_data[title]
updated_content = form.cleaned_data['form_content']
util.save_entry(title, updated_content)
return HttpResponseRedirect(reverse("entries:open_page", args=(title), ))
else:
return render(request, "encyclopedia/updatepage.html", {
"form": form
})
return render(request, "encyclopedia/updatepage.html", {
"form": NewPageForm(request.POST or None, initial=form_dict),
"titles": title,
})
The template:
{% block body %}
<h2>Update the {{titles}} entry:</h2>
<form action="{% url 'entries:update_page' title=titles %}" method="post">
{% csrf_token %}
{{ form.form_content}}
<input type="submit" value="Update">
</form>
<form method="GET" action="{% url 'entries:del_page' title=titles %}" >
<button type = "submit" >Delete Entry</button>
</form>
View Entries
{% endblock %}
Could you try removing str from the path, as str according to Django docs, matches any non-empty string, excluding the path separator, '/'. This is the default if a converter isn’t included in the expression.
app_name = "entries"
urlpatterns = [
path("", views.index, name="index"),
path("newpage", views.newpage, name="newpage"),
path("title/", views.open_page, name="open_page"),
path("search/", views.search, name="search_query"),
path("title/update", views.update_page, name="update_page"),
path("random/", views.random_page, name="random_page"),
path("title/deleted", views.del_page, name="del_page")
]

Django NoReverseMatch Argument

Doesn't find a suitable url from the list(I assume it takes a string for a tuple)
NoReverseMatch at /decision/livingrooms/kitchen/
Reverse for 'style' with arguments '('provans',)' not found. 1 pattern(s) tried:
['decision/livingrooms/(?P[-a-zA-Z0-9_]+)/(?P[-a-zA-Z0-9_]+)/$']
Template
<ul class="menu menu_interiors">
{% for room in rooms %}
<li class="menu__item menu__item_interiors">{{ room.name }}</li>
{% endfor %}
</ul>
<ul class="menu menu_styles">
{% for style in styles %}
<li class="menu__item menu__item_interiors">{{ style.name }}</li>
{% endfor %}
</ul>
urls.py
from django.urls import path
from .views import ContactView
from . import views
app_name = 'decision'
urlpatterns = [
path('livingrooms/', ContactView.as_view(), name='livingrooms'),
path('livingrooms/<slug:rmslg>/', views.room, name='room'),
path('livingrooms/<slug:rmslg>/<slug:stslg>/', views.style, name='style'),
]
views.py
def room(request, rmslg):
styles = Room.objects.get(slug=rmslg).styles.all()
print(len(styles))
return render(request, 'decision/residentialInteriors.html', {"styles": styles})
def style(request, stslg):
style = Style.objects.get(slug=stslg)
return render(request, 'decision/residentialInteriors.html', {"style": style})
Change the last path to accept only one parameter.
From:
path('livingrooms/<slug:rmslg>/<slug:stslg>/', views.style, name='style'),
To:
path('styles/<slug:stslg>/', views.style, name='style'), # Since your view only accepts one parameter, the URL should capture only one as well.
Final Result:
urlpatterns = [
path('livingrooms/', ContactView.as_view(), name='livingrooms'),
path('livingrooms/<slug:rmslg>/', views.room, name='room'),
path('styles/<slug:stslg>/', views.style, name='style'), # Since your view only accepts one parameter, the URL should capture only one as well.
]

Django – create pages along with the objects using the same template

This is my first time here.
I'm stuck with a little problem in Django. I'm writing a webpage for a kennel and I have a model for dogs. These dogs appear on the front page after they have been created in admin page. I need it so that after clicking any dog picture on the front page, you could get to their profile(with the dog's name in the URL) that should use one template for each of them.
Here is my code in models, views and urls:
models.py
class dog(models.Model):
name = models.CharField(max_length=30, blank=False, null=True)
main_image = models.ImageField(upload_to='dogs', blank=False, null=True)
MALE = 'ML'
FEMALE = 'FM'
gender_list = (
(MALE, 'male'),
(FEMALE, 'female'),
)
gender = models.CharField(max_length=2, choices=gender_list, default='gender')
description = models.TextField(max_length=500, blank=False, null=True)
birthday = models.DateField(default=datetime.today, blank=True)
slug = AutoSlugField(populate_from='name')
views.py
def home(request):
dog_list = list(dog.objects.all())
template = 'home.html'
return render(request, template, {'dogs' : dog_list})
def dog_view(request, slug):
dog_view = get_object_or_404(dog, slug=slug)
return render(request, 'profile.html', {'dog_view' : dog_view})
urls.py
urlpatterns = [
url(r'^$', views.home, name='home'),
url(r'^dogs/(?P<slug>[-\w]+)/$', views.dog_view, name='profile'),
url(r'^mating/', views.mating_list, name='mating'),
url(r'^admin/', admin.site.urls),
]
home.html
{% for dog in dogs %}
<a href="{% url 'profile' %}{{ dog.name }}">
<div class="col-sm-4">
<img class="img-circle img-responsive img-center" src="{{ dog.main_image.url }}" alt="">
<h2 align=center>{{ dog.name }}
<p>{{ dog.description }}</p>
</div>
{% endfor %}
I feel that it should be something very easy, although I searched over the internet and couldn't find how it is possible to have pages be automatically created along with the dog-objects.
Thank you very much in advance.
Try this:
views.py
def home(request):
dog_list = dog.objects.all()
template = 'home.html'
return render(request, template, {'dogs' : dog_list})
def dog_view(request, slug):
dog_view = get_object_or_404(dog, slug=slug)
return render(request, 'profile.html', {'dog_view' : dog_view})
home.html
{% for dog in dogs %}
{{ dog.name }}
<div class="col-sm-4">
<img class="img-circle img-responsive img-center" src="{{ dog.main_image.url }}" alt="">
<h2 align=center>{{ dog.name }}
<p>{{ dog.description }}</p>
</div>
{% endfor %}
urls.py
urlpatterns = [
url(r'^$', views.home, name='home'),
url(r'^dogs/(?P<slug>[-\w]+)/$', views.dog_view, name='profile'),
url(r'^mating/', views.mating_list, name='mating'),
url(r'^admin/', admin.site.urls),
]

Categories