My view is taking me to the same page over and over - django

Hey guys I made a model that can upload some files and then i made two views upload_list.html and upload_detail.html the list pages contains the links to the actual detail page but while clicking on the links it takes me to the same page again
Here,s the models.py
class Upload(models.Model):
image = models.ImageField(upload_to = 'images',)
file = models.FileField(upload_to = 'images/%Y/%M/%d/')
name = models.CharField(max_length = 200)
def __str__(self):
return self.name
def get_absolute_url(self):
return self.pk{}
Here,s the views.py
def upload_list(request):
upload_list = Upload.objects.all()
return render(request,'app/upload_list.html',{'upload_list':upload_list})
def upload_detail(request,pk):
upload_detail = get_object_or_404(Upload,pk = pk)
return render(request,'app/upload_detail.html',{'upload_detail':upload_detail})
Hers, the urls.py
url(r'^upload/',views.upload_list,name = 'upload_list'),
url(r'^upload/(?P<pk>[-\w]+)/$',views.upload_detail,name = 'upload_detail'),
Hers, the upload_list.html
{% extends 'app/base.html' %}
{% block content %}
{% load static %}
{% for i in upload_list %}
<div class="jumbotron">
{{i.name}}
<br>
</div>
{% endfor %}
{% include 'app/index_js.html' %}
{% endblock content %}
Here,s the upload_Detail.html
{% extends 'app/base.html' %}
{% block content %}
{% load static %}
<div class="jumbotron">
<h1>{{upload_detail.name}}</h1>
<img src="{{upload_detail.name}}" alt="'Image for you,r betterment "></img>
{{upload_detail.file}}
</div>
{% include 'app/index_js.html' %}
{% endblock conten`t %}`

Have you tried put your urls.py like this ?
url(r'^upload/$',views.upload_list,name = 'upload_list'),
url(r'^upload/(?P<pk>[-\w]+)/$',views.upload_detail,name = 'upload_detail'),
or
url(r'^upload/(?P<pk>[-\w]+)/$',views.upload_detail,name = 'upload_detail'),
url(r'^upload/$',views.upload_list,name = 'upload_list'),
The $ is a regex that indicates a end of string.
I hope that helps you

Related

Retrieve the human readable value of a charfield with choices via get_F00_display in Django views.py

What I want to do :
Display the human readable value of a charfield with choices via get_F00_display or other in views.py and then in template.
I have a Leave model for leaves management and want to display a template with all the leaves associated with the authenticated user.
What I have done :
Of course, I've read Django documentation (4.1) and find something interesting with get_F00_display but cannot make it works fine.
model.py (simplified)
class Leave(CommonFields):
LEAVES_TYPES = [
('10', _('Type 1')),
('20', _('Type 2')),
('30', _('Type 3')),
]
owner = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True)
type = models.CharField(max_length=3, choices=LEAVES_TYPES, null=True, default="10")
def __str__(self):
return self.owner.first_name + " " + self.owner.last_name + " : du " + self.begin_date.strftime("%d-%m-%Y") + " au " + self.end_date.strftime("%d-%m-%Y")
views.py
from django.shortcuts import render
from django.utils.translation import gettext as _
from .models import Leave
from django.views import generic
class LeaveListView(generic.ListView):
model = Leave
context_object_name = 'leave_list'
def get_queryset(self):
return Leave.objects.filter(is_active=True).values('type', 'begin_date','end_date','range','comment','status')
def get_context_data(self, **kwargs):
# Call the base implementation first to get the context
context = super(LeaveListView, self).get_context_data(**kwargs)
# Create any data and add it to the context
context['colHeaders'] = ['Type',
'From',
'To',
'Range',
'Comment',
'Status',]
return context
leave_list.html
{% extends "main/datatables.html" %}
<!-- TABLE TITLE -->
{% block tableTitle %}Leaves{% endblock %}
<!-- TABLE HEADER -->
{% block tableHeader %}
{% if colHeaders %}
{% for header in colHeaders %}
<th>{{header}}</th>
{% endfor %}
{% else %}
<p>No results</p>
{% endif %}
{% endblock %}
<!-- TABLE BODY -->
{% block tableBody %}
{% if leave_list %}
{% for leave in leave_list %}
<tr>
<td>{{leave.type}}</td>
<td>{{leave.begin_date}}</td>
<td>{{leave.end_date}}</td>
<td>{{leave.range}}</td>
<td>{{leave.comment}}</td>
<td>{{leave.status}}</td>
</tr>
{% endfor %}
{% else %}
<p>No results</p>
{% endif %}
{% endblock %}
<!-- TABLE FOOTER -->
{% block tableFooter %}
{% if colHeaders %}
{% for header in colHeaders %}
<th>{{header}}</th>
{% endfor %}
{% else %}
<p>No results</p>
{% endif %}
{% endblock %}
Problem :
{{leave.type}}
returns the key of the choices but I'm trying to display the human readable name in LEAVES_TYPES like "Type 1"...
What I've tried :
Using get_F00_display this way : get_type_display in my views.py :
def get_queryset(self):
return Leave.objects.filter(is_active=True).values(get_type_display, 'begin_date','end_date','range','comment','status')
Same thing in the template but no readable name displayed...

Django - Page not found (404) urls.py

problem:
Page not found (404)
Request Method: GET
Request URL: http://127.0.0.1:8000/home/category/coding/
Raised by: blogapp.views.BlogDetailView
urls.py
from django.urls.conf import path
from blogapp.views import BlogDetailView, BlogListView,searchposts,CatListView
from . import views
app_name = "blogapp"
urlpatterns = [
path('', views.BlogListView, name="blogs"),
path('home/search/', views.searchposts, name= "searchposts"),
path('home/category/<slug:_id>/', views.BlogDetailView, name="blog"),
path('home/category/<category>/', views.CatListView.as_view(), name="category"),
]
if i reverse this two
path('home/category/<slug:_id>/', views.BlogDetailView, name="blog"),
path('home/category/<category>/', views.CatListView.as_view(), name="category"),
it shows the html of the category , and the path of 'path('home/category/slug:_id/', views.BlogDetailView, name="blog"),' is not showing , vice versa
here is the html of navbar
{% for category in category_list %}
{% if forloop.counter < 4 %}
<li class="nav-item">
<a class="nav-link" href="home/category/{{category.name}}">{{ category.name|title }}</a>
</li>
{% endif %}
{% endfor %}
html that i want to render
{% extends "_layouts/base.html" %}
{% block css %}
{{block.super}}
{% endblock css %}
{% block page_title %}Insert_your_name_here{% endblock %}
{% load static %} <!-- load the image -->
{% block maincontent %}
<!-- Banner -->
{% block banner %}
{% load static %}
{% include "layout/category_banner.html" %}
{% endblock %}
<!-- Banner Here -->
!-- This is the main template -->
<section class="blog-posts grid-system">
<div class="container">
<div class="row">
<div class="col-lg-8">
<div class="all-blog-posts">
<div class="row">
{% block categories-main %}
{% include "layout/category.html" %}
{% endblock %}
</div>
</div>
</div>
{% block sidebars %}
{% load static %}
{% include "layout/Sidebars.html" %}
{% endblock %}
</div>
</div>
</section>
{% endblock %}
here is my views.py
def BlogDetailView(request,_id):
try:
category_list = Category.objects.exclude(name='default')
dataset = BlogModel.newmanager.all()
data = BlogModel.newmanager.get(slug =_id)
comments = CommentModel.objects.filter(blog = data, status=True)
except BlogModel.DoesNotExist:
raise Http404('Data does not exist')
if request.method == 'POST':
form = CommentForm(request.POST)
if form.is_valid():
Comment = CommentModel(your_name= form.cleaned_data['your_name'],
comment = form.cleaned_data['comment'],
blog=data)
Comment.save()
return redirect(f'/home/category/{_id}')
else:
form = CommentForm()
context = {
'data':data,
'form':form,
'comments':comments,
'dataset': dataset,
"category_list": category_list,
}
return render(request,'layout/post-details-main.html',context)
def searchposts(request):
dataset = BlogModel.newmanager.all()
if request.method == 'GET':
query= request.GET.get('q')
submitbutton= request.GET.get('submit')
if query is not None:
lookups= Q(blog_title__icontains=query) | Q(blog__icontains=query)
results= BlogModel.objects.filter(lookups).distinct()
context={'results': results,
'submitbutton': submitbutton,
'dataset': dataset,
}
return render(request, 'layout/search-main.html', context)
else:
return render(request, 'layout/search-main.html')
else:
return render(request, 'layout/search-main.html')
class CatListView(ListView):
template_name = 'layout/category-main.html'
context_object_name = 'catlist'
def get_queryset(self):
content = {
'cat' : self.kwargs['category'],
'posts' :
BlogModel.objects.filter(category__name=self.kwargs['category']).filter(status='published')
}
return content
def category_list(request):
category_list = Category.objects.exclude(name='default')
context = {
"category_list": category_list,
}
return context
it says that the problem is raised by blogapp.views.BlogDetailView so i added this to my BlogDetailView render it to my main html :
category_list = Category.objects.exclude(name='default')
context = {
"category_list": category_list,
}
i think the problem is the link? of my navbar or the BlogDetailView?, What is the problem of this?
You have to accept it as string
Try like this:
path('home/category/<str:category>/', views.CatListView.as_view(), name="category"),
Case is solved i using both str and slug, so my category does not match to my _id, need to match those two
path('home/category/<slug:category>/', views.CatListView.as_view(), name="category"),
path('home/category/<slug:_id>/', views.BlogDetailView, name="blog")

How to delete a record through a button in django

I have created a model Announcement in models.py file
class Announcement(models.Model):
title = models.CharField(max_length=30)
content = models.TextField()
date_posted = models.DateTimeField(default=timezone.now)
teacher = models.ForeignKey(Teacher, on_delete=models.CASCADE)
def __str__(self):
return self.title
And for deleting a record of Announcement I have created the following view
def AnnouncementDelete(request, pk):
announcement = get_object_or_404(Announcement, pk=pk)
if request.method=='POST':
announcement.delete()
return redirect('/')
return render(request, 'classroom/announcement_confirm_delete.html', {'announcement': announcement})
The delete view of announcement (that is AnnouncementDelete) has the following url
path("delete/<int:pk>/", view=views.AnnouncementDelete, name="AnnouncementDelete"),
If i enter
http://127.0.0.1:8000/classroom/delete/3
on browser it is deleting the Announcement having pk = 3
Now I want a button to directly delete my record without the need of typing http://127.0.0.1:8000/classroom/delete/3 on browser
I have tried the following methods in my allannouncement.html file
{% extends "classroom/base.html" %}
{% block content %}
<h1>Announcements</h1>
{% for announcement in announcements %}
<!-- starting loop (posts is keyword from view) -->
<div style="border-style: solid;">
{% if announcement.teacher.user == request.user %}
<div>
Delete
</div>
{% endif %}
{{ announcement.pk }}
<a class="mr-2">Posted by: {{ announcement.teacher }}</a>
<h2><a class="article-title">{{ announcement.title }}</a></h2>
<p class="article-content">{{ announcement.content}}</p>
</div>
{% endfor %}
{% endblock content %}
but it is giving the following error
NoReverseMatch at /classroom/allannouncement/
Reverse for 'AnnouncementDelete' with no arguments not found. 1 pattern(s) tried: ['classroom/delete/(?P<pk>[0-9]+)/$']
then I also tried passing pk with url like
Delete
But it is giving the following error
TemplateSyntaxError at /classroom/allannouncement/
Could not parse the remainder: ',' from ','
Remove common #refer this
Delete
instead of a link add a form.
Add
{% load crispy_forms_tags %}
in your html file and then add
{% if announcement.teacher.user == request.user %}
<div>
<form action="{% url 'classroom:AnnouncementDelete' announcement.id %}"
method="post">
{% csrf_token %}
<input type="submit" value="Delete">
</form>
</div>
{% endif %}

Django simple tag doesn't work in if condition

I want to customize django-admin's change form for video objects by adding block with moderation tools.
When I use custom simpletags in if condition - it doesn't work.
models.py:
class Video(models.Model):
class Meta:
db_table = 'video'
DRAFT = 1
MODERATION = 2
PUBLISHED = 3
REJECTED = 4
HOSTING_UPLOADING = 5
SUSPICIOUS = 6
PUBLICATION_STATUSES = (
(DRAFT, 'draft'),
(MODERATION, 'moderation'),
(PUBLISHED, 'published'),
(HOSTING_UPLOADING, 'hosting uploading'),
(REJECTED, 'rejected'),
(SUSPICIOUS, 'suspicious')
)
video_pk = models.AutoField(primary_key=True)
name = models.CharField(max_length=150, blank=True)
hosting_id = models.CharField(max_length=20, blank=True)
publication_status = models.PositiveSmallIntegerField(choices=PUBLICATION_STATUSES, default=MODERATION)
templatetags video_publication_statuses.py:
from api.models import Video
from django import template
register = template.Library()
#register.simple_tag
def moderation(status):
return status == Video.MODERATION
#register.simple_tag
def suspicious(status):
return status == Video.SUSPICIOUS
#register.simple_tag
def published(status):
return status == Video.PUBLISHED
#register.simple_tag
def hosting_uploading(status):
return status == Video.HOSTING_UPLOADING
#register.simple_tag
def rejected(status):
return status == Video.REJECTED
change_form.html:
{% extends "admin/change_form.html" %}
{% load video_publication_statuses %}
{% suspicious original.publication_status as suspicious_status %}
{% moderation original.publication_status as moderation_status %}
{% hosting_uploading original.publication_status as hosting_uploading_status %}
{% published original.publication_status as published_status %}
{% rejected original.publication_status as rejected_status %}
{% block after_related_objects %}
{% if original.pk %}
{% for fieldset in adminform %}
{% if fieldset.name == 'Moderation' %}
{% include "admin/includes/fieldset.html" %}
{% endif %}
{% endfor %}
<div class="submit-row">
{% if rejected_status or moderation_status or suspicious_status %}
<input type="submit" value="Publish" name="publish" >
{% endif %}
{% if published_status %}
<input type="submit" value="Reject" name="reject" >
{% endif %}
</div>
{% endif %}
{% endblock %}
When I use explicit values instead of tags it works:
{% if original.publication_status == 3 %}
<input type="submit" value="Reject" name="reject" >
{% endif %}
Please help me understand what is wrong with tags?
I believe this is happening because template tags pass strings and you're checking a string against an integer e.g. return "3" == 3
Broadly speaking though, you're putting a lot of logic in a template and I typically avoid that situation. Template tags are reserved for "presentation logic" and I take that to mean "changing the way something is presented", not changing what is viewed. That logic belongs in a view or the model itself.
It should be easy enough to put this logic on your model.
class Original(...):
def rejected(self):
return self.status == Video.rejected

Can't use Django's get_absolute_url in dictionary of dictionaries?

I'm having some trouble using get_absolute_url in a template. It seems to work fine if I just pass in one of my store objects and say {{ store.get_absolute_url }}, but if I have to iterate through a dictionary of stores and then use the get_absolute_url function, it returns nothing. Exactly what I'm doing is below:
class Store(EthicalObject):
type = "Store"
name = models.CharField(max_length=50)
company = models.ForeignKey(Company, verbose_name="Company", null=True, blank=True)
location = models.OneToOneField(Location, verbose_name="Location", null=True, blank=True)
products = models.ManyToManyField('Product', related_name="%(class)s_related", db_table=u'ethicsdb_products_to_stores', blank=True)
companies = models.ManyToManyField('Company', related_name="%(class)s_related", db_table=u'ethicsdb_companies_to_stores', blank=True)
def get_absolute_url(self):
return ('store_details', [str(self.id)])
get_absolute_url = models.permalink(get_absolute_url)
This works:
views.py:
def fetch_sidebar_data(shop_object):
sidebar_modules = {}
if shop_object.content_type.name == 'company':
sidebar_modules['related_stores'] = shop_object.stores.all()
sidebar_modules['related_products'] = shop_object.products.all()
if shop_object.content_type.name == 'store':
sidebar_modules['related_companies'] = shop_object.companies.all()
sidebar_modules['related_products'] = shop_object.products.all()
if shop_object.content_type.name == 'product':
sidebar_modules['related_stores'] = shop_object.stores.all()
sidebar_modules['related_companies'] = shop_object.companies.all()
sidebar_modules['tags'] = shop_object.tags
return sidebar_modules['related_stores'][1]
def company_details(request, company_id):
company = get_object_or_404(Company, id=company_id)
sidebar_modules = fetch_sidebar_data(company)
return render_to_response('company/details.html', {'company': company, 'sidebar_modules': sidebar_modules}, context_instance=RequestContext(request))
template:
{% extends "base-onecol.html" %}
{% block page_div_extra_attr %}class="twocol"{% endblock %}
{% block sidebar_content %}
<div id="sidebar-right">
<h1>{{ sidebar_modules.name }}{{sidebar_modules.get_absolute_url }}</h1>
</div>
{% endblock %}
This doesn't work:
views.py:
def fetch_sidebar_data(shop_object):
sidebar_modules = {}
if shop_object.content_type.name == 'company':
sidebar_modules['related_stores'] = shop_object.stores.all()
sidebar_modules['related_products'] = shop_object.products.all()
if shop_object.content_type.name == 'store':
sidebar_modules['related_companies'] = shop_object.companies.all()
sidebar_modules['related_products'] = shop_object.products.all()
if shop_object.content_type.name == 'product':
sidebar_modules['related_stores'] = shop_object.stores.all()
sidebar_modules['related_companies'] = shop_object.companies.all()
sidebar_modules['tags'] = shop_object.tags
return sidebar_modules
template:
{% extends "base-onecol.html" %}
{% block page_div_extra_attr %}class="twocol"{% endblock %}
{% block sidebar_content %}
<div id="sidebar-right">
{% for module_name,module in sidebar_modules.items %}
{% ifequal module_name "related_stores" %}
<h3>Sold Here</h3>
{% for related_store in module.values %}
{{ related_store.name }}<br/>
{% endfor %}
{% endifequal %}
{% ifequal module_name "related_products" %}
<h3>Buy Local</h3>
{{ module }}<br/>
{% endifequal %}
{% ifequal module_name "related_companies" %}
<h3>
{{ module }}<br/>
{% endifequal %}
{% ifequal module_name "tags" %}
{{ module }}<br/>
{% endifequal %}
{% endfor %}
</div>
{% endblock %}
In the second one, I just get no return from get_absolute_url. I know it's working in other places when I print it out. Is this a Django bug, the inability to use get_absolute_url in a dictionary of dictionaries?
Wow, that was a rather convoluted question.
Your problem is here: {% for related_store in module.values %}
module is a QuerySet. .values is calling the QuerySet method which returns a dictionary containing the field values for each row. A dictionary has no get_absolute_url attribute, and get_absolute_url isn't a field in the model.
Just use {% for related_store in module %} and you'll be dealing with actual model instances rather than dictionaries, which means {{ related_store.get_absolute_url }} will work fine.