how to make sub pages url in django - python

In my online store django project, I want to create a sub-page which shows the details of a product that is listed in a page.
in urls.py I created the urls for both pages like bellow:
path('wwqm', views.water_quality_sensor , name='wwqm'),
path('wwqm/<str:water_sensor_title>', views.water_sensor_item, name='water_sensor_item'),
in this scenario, a bunch of items are being shown in wwqm. user click on a product and the water_sensor_item should load up.
I know its not important but here is views.py:
def water_quality_sensor(request):
queryset_list = Water_quality_sensor.objects.order_by('-product_name').filter(is_published=True)
context = {
'water_quality_sensor': queryset_list,
}
return render(request, 'products/water_quality_sensor.html', context)
def water_sensor_item(request, water_sensor_title):
water_sensors = get_object_or_404(Water_quality_sensor, title=water_sensor_title)
context = {
'water_sensors': water_sensors
}
return render(request, 'products/water_sensor_item.html' , context)
I try to build the url for each item based on a parameter that is passed to its view(products title).
In my templates, I try to create a link like the following:
<a href="{% url 'water_sensor_item' w_q_sensor.title %}" class="card hoverable mb-4 text-dark" >
one my products' title is 3725. when I click on that product in the main page, I get the following error:
Django Version: 3.1.2
Exception Type: NoReverseMatch
Exception Value: Reverse for 'water_quality_sensor' not found. 'water_quality_sensor' is not a valid view function or pattern name.
What am I doing wrong?

in your urls.py
path('wwqm', views.water_quality_sensor , name='wwqm'),
you used name wwqm. But it looks like somewhere in your template (most likely water_sensor_item.html), you have something similar to :
<a href="{% url 'water_quality_sensor' %}"
Change it to wwqm or change name in urls.py
UPDATE
It is better to use <str:title><int:pk> in your urls, to avoid when you have the same name in two products. pk is unique.
in your urls.py
path('wwqm/<str:water_sensor_title><int:pk>', views.water_sensor_item, name='water_sensor_item'), # add <int:pk>
in your template:
# since url is taking both title and pk arguments, you need to provide both of them.
<a href="{% url 'water_sensor_item' title= w_q_sensor.title pk=w_q_sensor.pk %}" class="card hoverable mb-4 text-dark" >
in your view:
def water_sensor_item(request, water_sensor_title, pk): # added pk
water_sensors = get_object_or_404(Water_quality_sensor, pk=pk) # use pk to get the object
context = {
'water_sensors': water_sensors
}
return render(request, 'products/water_sensor_item.html' , context)

Related

How to use string of <li> in django view?

I am building a blog where users can click on several <li> items in the sidebar to show blog posts according to the clicked category.
The desired outcome is somewhat to the official documentation, so that I will end up with /blog/category and the according blog posts rendered.
The problem is that if I visit the main page (or http://127.0.0.1:8000/ in development) it raises an error
render_blog() missing 1 required positional argument: 'category'
So how can I use the view render_blog both for the main page and for the categories clicked to render the according blog posts?
html
<li class="navigation-item" id="spotlights-item">
<div id="spotlights-ctn">Hot Stocks<img id="fire-icon" src="{% static 'images/fire.svg' %}" alt="finsphere.io"></div>
</li>
urls
urlpatterns = [
path('AsiaPacific/<category>', render_blog, name='AsiaPacific'),
url(r'^$', render_blog, name='render_blog'),
]
views.py
def render_blog(request, category):
category = category
if not category:
# Main blog as landing page
# Get 5 latest posts and order by publish date, newest first
posts = Post.objects.filter(publish_date__lte=now).order_by('-publish_date')[:5]
return render(request, 'blog/blog.html', {'posts': posts})
else:
# Blog displayed as Category Selection
posts = Post.objects.filter(categories__title=category, publish_date__lte=now)
return render(request, 'blog/blog.html', {'posts': posts})
Im not 100% sure I'm following, but you don't have to use the href on an anchor tag to link anywhere. You can just set href="" and give every link a class such as "category-link". Then tie your ajax onclick event to the class, and have the code first pull the text or another attribute from the link and submit it as a variable:
$('.category-link').on('click', function() {
var link = $(this);
var page = link.data('page');
var category = link.data('category');
$.ajax({
type: 'post',
url: '/lazy_load_posts/',
data: {
'page': page,
'category': category,
'csrfmiddlewaretoken': window.CSRF_TOKEN // from blog.html
},
(...)

Two variables in Django URL

I want a URL something like this:
/(category)/(post-slug)
On the link this is what I have:
{% url blog.category blog.slug %}
and for the url.py:
url(r'^(I DON"T KNOW WHAT TO PUT ON THIS PART TO GET THE CATEGORY)/(?P<slug>[0-9A-Za-z._%+-]+)', views.post, name='post'),
thanks
EDIT:
This is what I have now:
Still have NoReverseMatch error at /
urls.py
url(r'^(?P<category>[0-9A-Za-z._%+-]+)/(?P<slug>[0-9A-Za-z._%+-]+)$', views.post, name='post'),
index.html
<a href="{% url blog.category blog.slug %}">
views.py
def post(request, slug, category):
try:
blog = Blog.objects.get(slug=slug)
except Blog.DoesNotExist:
raise Http404('This post does not exist')
return render(request, 'parts/post.html', {
'blog': blog,
})
Firstly, your URL tag needs the name of the pattern you are reversing as the first argument:
{% url 'post' blog.category blog.slug %}
or if you are using a namespace, something like:
{% url 'blog:post' blog.category blog.slug %}
You haven't shown your views or models, so we can only guess what your URL pattern should be. I'm not sure why you find the category confusing - you just need to choose a name for the group (e.g. category_slug), and the regex for the group (you might be able to use the same one as you use for slug). That would give you:
url(r'^(?P<category_slug>[0-9A-Za-z._%+-]+)/(?P<slug>[0-9A-Za-z._%+-]+)$'
Note that there should be a dollar on the end of the regex.

Django: Images/Absolute URLS from not displaying in html

I have a block of code on my template which does not show up on my html nor does it give any error on Chromes console. I am trying to display a list of images which when clicked takes you to the detail of that image.
Here is the key part of my HTML(base.html):
<div class="container-fluid">
<h2>Popular</h2> #only this shows up
{% for obj in object_list %}
<img src = "{{ obj.mpost.url}}" width="300"><br>
<a href='/m/{{ obj.id }}/'> {{obj.username}} </a><br/>
{% endfor %}
</div>
views.py:
from django.shortcuts import render,get_object_or_404
from .models import m
# Create your views here.
def home(request):
return render(request,"base.html",{})
def m_detail(request,id=None):
instance = get_object_or_404(m,id=id)
context = {
"mpost": instance.mpost,
"instance": instance
}
return render(request,"m_detail.html",context)
def meme_list(request): #list items not showing
queryset = m.objects.all()
context = {
"object_list": queryset,
}
return render(request, "base.html", context)
urls.py:
urlpatterns = [
url(r'^$', home, name='home'),
url(r'^m/(?P<id>\d+)/$', m_detail, name='detail'),#issue or not?
]
models.py:
class m(models.Model):
username = "anonymous"
mpost = models.ImageField(upload_to='anon_m')
creation_date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return m.username
Thank you so much for your time. :)
I assume the problem is the fact that you don't have a url at all for the meme list, so either you're showing the home view and need to move the code from the meme_list view into your home view, or you need to make a url for the meme_list (and navigate to that new url instead)

NoReverseMatch - Simple Django forums application

I am attempting to create a simple forum application and am getting this error. I am inclined to think this may have something to do with my URLConf or possibly the way I am using the URL template tag to generate the URL for each thread.
/forums/urls.py
# ex: /forums/general_forum
url(r'^(?P<forum_slug>[-\w\d]+)/$', views.forum, name='forum'),
# ex: /forums/general_forum-1/my_first_thread
url(r'^(?P<forum_slug>[-\w\d]+)/(?P<thread_slug>[-\w\d]+)/$', views.thread, name='thread'),
/forums/views.py
The index view works fine, the forum view does not.
def index(request):
context = RequestContext(request)
forum_list = Forum.objects.order_by("sequence")
for forum in forum_list:
forum.url = slugify(forum.title) + "-" + str(forum.id)
context_dict = {'forum_list': forum_list}
return render_to_response('forums/index.html', context_dict, context)
#login_required
def forum(request, forum_slug):
context = RequestContext(request)
try:
forum = Forum.objects.get(slug=forum_slug)
threads = Thread.objects.filter(forum=forum)
context_dict = {'forum': forum,
'threads': threads}
except Forum.DoesNotExist:
pass
return render_to_response('forums/forum.html', context_dict, context)
This is how I am linking to the forum view inside index.html.
<a href={% url 'forum' forum.slug %}>{{ forum.title }}</a>
And in forum.html, this is how the links are formulated to view the posts inside the thread. This :
<a href={% url 'forum' forum.slug %}/{% url 'thread' thread.slug %}>{{ thread.title }}</a>
The error. One of the threads is titled 'django'
NoReverseMatch at /forums/web-development/
Reverse for 'thread' with arguments '(u'django',)' and keyword arguments '{}' not found. 2 pattern(s) tried: ['forums/(?P<forum_slug>[-\\w\\d]+)/(?P<thread_slug>[-\\w\\d]+)/$', '$(?P<forum_slug>[-\\w\\d]+)/(?P<thread_slug>[-\\w\\d]+)/$']
In the error, the url template tag for 'thread' is highlighted in red and states there was an error during template rendering. This error seems unclear to me and I am not sure if this is an issue with the way I am using the template tags or something else.
You're not passing the Forum slug in your thread URL, which your URL configuration requires:
<a href={% url 'forum' forum.slug %}/{% url 'thread' thread.slug %}>{{ thread.title }}</a>
You should not be using both urls, either. Instead, what you want is:
{{ thread.title }}

get_full_path in django model method

I'm just starting with django (and python too, to be honest)
I am trying to get a model method that would cut the self.slug from current URL and return it to template.
This is the method I tried:
class Category(models.Model):
...
def remove_filter(self):
url = HttpRequest.get_full_path()
slug = '/' + self.slug
return url.replace(slug, '')
But as you can imagine, it doesn't work.
Template's snippet:
{% for object in active_filters %}
<li><i class="icon-remove"></i>{{ object }}</li>
{% endfor %}
My core goal here is to have a front-end icon with a url altered by removing current object's slug.
I have no idea how to do it through views, but I'm open to any suggestions.
def category_page(request, url):
slugs = url.split('/')
active = Category.objects.filter(slug__in=slugs)
sorted_slugs = []
for i in active:
sorted_slugs.append(i.slug)
if slugs != sorted_slugs:
url = '/'.join(sorted_slugs)
return redirect('http://127.0.0.1:8000/catalog/' + url)
inactive = Category.objects.exclude(slug__in=slugs)
return render(request, 'category.html', {'active_filters': active,
'inactive_filters': inactive})
Thanks.
You can send a list of all active slugs to the template and then build a custom template filter to construct the modified url.
views.py
# Send your list of active slugs to the template
return render(request, 'category.html', {
'active_filters': active,
'inactive_filters': inactive,
'slugs': slugs,
})
tags_and_filters.py
import copy
from django import template
register = template.Library()
#register.filter(name='remove_filter')
def remove_filter(category, slugs):
copied_slugs = copy.copy(slugs)
slug = category.slug
if slug in copied_slugs:
copied_slugs.remove(slug)
return '/'.join(copied_slugs)
your template
{% for object in active_filters %}
<li>
<i class="icon-remove"></i>{{ object }}
</li>
{% endfor %}
Your remove_filter method has no access to the current request. HttpRequest is the class, not the current request instance.
I suggest that you rewrite remove_filter as a custom tag or filter. That way your function can access the category and request instance. You will have to activate the request template context processor in your settings as well.

Categories

Resources