I am new to django and I don't know what to do now. I have this error:
NoReverseMatch at /account/show-my-posts/5/
Reverse for 'delete' with arguments '(15, 5)' not found. 1 pattern(s)
tried: ['account/delete///']
My views('ShowMyPosts' and 'delete_post'):
class ShowMyPosts(APIView):
renderer_classes = [TemplateHTMLRenderer]
template_name = 'show_my_posts.html'
def get(self, request, pk, format=None):
posts = Post.objects.all().filter(user=pk)
serializerPosts = PostSerializer(posts,many=True)
pprint.pprint(json.loads(JSONRenderer().render(serializerPosts.data))
return Response({'posts': serializerPosts.data})
def delete_post(request,post_id=None,pk=None):
post_to_delete = Post.objects.get(id=post_id)
post_to_delete.delete()
return HttpResponseRedirect('/account/show-my-posts/' + pk + '/')
Template:
{% extends 'base2.html' %}
{% block content %}
<div class="container">
<div class="row">
<div class="col-md-3 ">
<div class="list-group ">
Profile
My Posts
</div>
</div>
<form method="post" action="" class="form-signin">
{% for post in posts %}
<div id="cardme" style="padding:20px;margin-left:-100px">
<div class="card text-center " style="width: 30rem;">
<img class="card-img-top" src='{{post.profile_image}}' alt="Card image cap">
<div class="card-body">
<h5 class="card-title">{{post.title}}</h5>
<h6 class="card-subtitle mb-2 text-muted">{{ post.created_date}}</h6>
<p class="card-text">{{post.text}}</p>
<button class="btn btn-primary">Delete</button>
</div>
</div>
</div>
{% endfor %}
</form>
</div>
</div>
{% endblock %}
URL:
url(r'show-my-posts/(?P<pk>[0-9]+)/', login_required(views.ShowMyPosts.as_view()), name='show_my_posts'),
url(r'delete/<post_id>/<pk>/',views.delete_post,name='delete'),
There is some problem with your URLs. When you want pass a variable to url, you should use regex to do that. Take a look at this example :
url(r'^posts/(?P<id>\d+)/$', views.PostDetail.as_view(), name='post_detail')
Also, if you want use normal way, you should specify a data type there :
path('posts/<int:id>/', views.PostDetail.as_view(), name='post_detail')
For more information about URL dispatching, see this documentation
Related
I have searched through the other questions similar to my own problem and have come to no solution so im hoping someone can help me figure out where i went wrong.
I'm trying to implement a delete post option in my blog program but it is throwing the following error once you click the 'delete' button:
ImproperlyConfigured at /18/delete/
Deletepost is missing a QuerySet. Define Deletepost.model, Deletepost.queryset, or override Deletepost.get_queryset().
I am nearly sure its a problem with my URLS.py though what exactly i cannot figure out.
the following is the code in question:
Views.py
# delete post
class Deletepost(LoginRequiredMixin, DeleteView):
form_class = Post
success_url = reverse_lazy('blog:home')
template_name = 'templates/post.html'
def test_func(self):
post = self.get_object()
if self.request.user == post.author:
return True
return False
urls.py
urlpatterns = [
# home
path('', views.postslist.as_view(), name='home'),
# add post
path('blog_post/', views.PostCreateView.as_view(), name='blog_post'),
# posts/comments
path('<slug:slug>/', views.postdetail.as_view(), name='post_detail'),
# edit post
path('<slug:slug>/edit/', views.Editpost.as_view(), name='edit_post'),
# delete post
path('<int:pk>/delete/', views.Deletepost.as_view(), name='delete_post'),
# likes
path('like/<slug:slug>', views.PostLike.as_view(), name='post_like'),
]
post.html
{% extends 'base.html' %} {% block content %}
{% load crispy_forms_tags %}
<div class="masthead">
<div class="container">
<div class="row g-0">
<div class="col-md-6 masthead-text">
<!-- Post title goes in these h1 tags -->
<h1 class="post-title text-success">{{ post.title }}</h1>
<!-- Post author goes before the | the post's created date goes after -->
<p class="post-subtitle text-success">{{ post.author }} | {{ post.created_on }}</p>
</div>
<div class="d-none d-md-block col-md-6 masthead-image">
<!-- The featured image URL goes in the src attribute -->
{% if "placeholder" in post.featured_image.url %}
<img src="https://codeinstitute.s3.amazonaws.com/fullstack/blog/default.jpg" width="100%">
{% else %}
<img src=" {{ post.featured_image.url }}" width="100%">
{% endif %}
</div>
</div>
</div>
</div>
<div class="container">
<div class="row">
<div class="col card mb-4 mt-3 left top">
<div class="card-body text-dark">
<!-- The post content goes inside the card-text. -->
<!-- Use the | safe filter inside the template tags -->
<p class="card-text text-dark">
{{ post.content | safe }}
</p>
<div class="row">
<div class="col-1">
<strong>
{% if user.is_authenticated %}
<form class="d-inline" action="{% url 'post_like' post.slug %}" method="POST">
{% csrf_token %}
{% if liked %}
<button type="submit" name="blogpost_id" value="{{post.slug}}" class="btn-like"><i class="fas fa-heart"></i></button>
{% else %}
<button type="submit" name="blogpost_id" value="{{post.slug}}" class="btn-like"><i class="far fa-heart"></i></button>
{% endif %}
</form>
{% else %}
<span class="text-secondary"><i class="far fa-heart"></i></span>
{% endif %}
<!-- The number of likes goes before the closing strong tag -->
<span class="text-secondary">{{ post.number_of_likes }} </span>
</strong>
</div>
<div class="col-1">
{% with comments.count as total_comments %}
<strong class="text-dark"><i class="far fa-comments"></i>
<!-- Our total_comments variable goes before the closing strong tag -->
{{ total_comments }}</strong>
{% endwith %}
</div>
<div class="col-1">
<a class="btn btn-outline-danger" href="{% url 'delete_post' post.id %}">Delete It</a>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col">
<hr>
</div>
</div>
<div class="row">
<div class="col-md-8 card mb-4 mt-3 ">
<h3 class="text-dark">Comments:</h3>
<div class="card-body">
<!-- We want a for loop inside the empty control tags to iterate through each comment in comments -->
{% for comment in comments %}
<div class="comments text-dark" style="padding: 10px;">
<p class="font-weight-bold">
<!-- The commenter's name goes here. Check the model if you're not sure what that is -->
{{ comment.name }}
<span class=" text-muted font-weight-normal">
<!-- The comment's created date goes here -->
{{ comment.created_on }}
</span> wrote:
</p>
<!-- The body of the comment goes before the | -->
{{ comment.body | linebreaks }}
</div>
<!-- Our for loop ends here -->
{% endfor %}
</div>
</div>
<div class="col-md-4 card mb-4 mt-3 ">
<div class="card-body">
<!-- For later -->
{% if commented %}
<div class="alert alert-success" role="alert">
Your comment is awaiting approval
</div>
{% else %}
{% if user.is_authenticated %}
<h3 class="text-dark">Leave a comment:</h3>
<p class="text-dark">Posting as: {{ user.username }}</p>
<form class="text-dark" method="post" style="margin-top: 1.3em;">
{{ comment_form | crispy }}
{% csrf_token %}
<button type="submit" class="btn btn-signup btn-lg">Submit</button>
</form>
{% endif %}
{% endif %}
</div>
</div>
</div>
</div>
{% endblock content %}
Any ideas?
I think it should be model not form_class so:
class Deletepost(LoginRequiredMixin, DeleteView):
model = Post
success_url = reverse_lazy('blog:home')
template_name = 'templates/post.html'
def test_func(self):
post = self.get_object()
if self.request.user == post.author:
return True
return False
#SunderamDubey's answer is correct. The test_func will however not run, since this is method of the UserPassesTestMixin [Django-doc], not LoginRequiredMixin.
But using a test function as is done here is not efficient: it will fetch the same object twice from the database. You can simply restrict the queryset, like:
from django.contrib.auth.mixins import LoginRequiredMixin
from django.urls import reverse_lazy
from django.views.generic import DeleteView
class DeletePostView(LoginRequiredMixin, DeleteView):
model = Post
success_url = reverse_lazy('blog:home')
template_name = 'templates/post.html'
def get_queryset(self, *args, **kwargs):
return (
super().get_queryset(*args, **kwargs).filter(author=self.request.user)
)
This will do filtering at the database side, and thus return a 404 in case the logged in user is not the author of the Post object you want to delete.
In the template, you will need to make a mini-form to make a POST request, for example:
<form method="post" action="{% url 'delete_post' post.id %}">
{% csrf_token %}
<button class="btn btn-outline-danger" type="submit">Delete</button>
</form>
In my opinion, you should change url to below
'path('delete/int:pk', views.Deletepost.as_view(), name='delete_post'),'
if didn't work you can do this
def delete_post(request, post_id):
post = Post.objects.get(pk=post_id)
post.delete()
return redirect('blog:home')
Im not gonna lie, this doesnt make any sense to me, why is this trying to access 'post-details' instead of 'create-post' and how do I fix it? Thank you in advance
error:
NoReverseMatch at /create/
Reverse for 'post-details' with arguments '('',)' not found. 1 pattern(s) tried:
['(?P[-a-zA-Z0-9_]+)/post/$']
Request Method: GET
Request URL: http://127.0.0.1:8000/create/
Django Version: 3.2.2
Exception Type: NoReverseMatch
Exception Value:
Reverse for 'post-details' with arguments '('',)' not found. 1 pattern(s) tried: ['(?P[-a-zA-Z0-9_]+)/post/$']
Post create view:
class PostCreate(CreateView):
model = Post
form_class = PostCreateForm
template_name = 'post/post_create.html'
context_object_name = 'form'
def get_success_url(self):
return reverse('post:home')
def form_valid(self, form):
form.instance.author = self.request.user.profile
return super().form_valid(form)
My urls:
from django.urls import path, include
from . import views
app_name = 'post'
urlpatterns = [
path('', views.PostList.as_view(), name='home'),
path('<slug:slug>/post/', views.PostDetails.as_view(), name='post-details'),
path('search/', views.search, name='search'),
path('comment-delete/<pk>/', views.CommentDelete.as_view(), name='comment-delete'),
path('comment-update/<pk>/', views.CommentUpdate.as_view(), name='comment-update'),
path('tag/<str:name>/', views.PostTagList.as_view(), name='tag-posts'),
path('create/', views.PostCreate.as_view(), name='create-post')
]
post_create.html file from my PostCreate view:
{% extends 'base.html' %}
{% block content %}
<div class="container mt-5 mb-5">
<form action="" class="commenting-form" method="post" enctype="multipart/form-data">
<div class="row">
<div class="form-group col-md-12">
{% csrf_token %}
{{ form.tags }}
<div class="form-group col-md-12">
<button type="submit" class="btn btn-secondary mt-2">Edit comment</button>
</div>
</div>
</div>
<div class="row">
<div class="form-group col-md-12">
{% csrf_token %}
{{ form.body }}
{{ form.picture }}
<div class="form-group col-md-12">
<button type="submit" class="btn btn-secondary mt-2">Edit comment</button>
</div>
</div>
</div>
</form>
<hr>
<a class="btn btn-info" href="{% url 'post:post-details' post_slug %}">Back</a>
</div>
{% endblock content %}
How im passing the slug value to the 'post-details'
{% extends 'base.html' %}
{% load static %}
{% block content %}
<div class="container">
<div class="row">
<!-- Latest Posts -->
<main class="posts-listing col-lg-8">
<div class="container">
<div class="row">
{% for post in posts %}
<div class="post col-xl-6">
<div class="post-thumbnail">
<a href="{% url 'post:post-details' post.slug %}">
<img src="{{ post.picture.url }}" alt="..." class="img-fluid post-picture">
</a>
</div>
<div class="post-details">
<div class="post-meta d-flex justify-content-between">
<div class="date meta-last">{{ post.created|timesince }}</div>
<div class="category">
{% for tag in post.tags.all %}
{{ tag }}
{% endfor %}
</div>
</div>
<p class="text-muted">{{ post.body }}</p>
<div class="post-footer d-flex align-items-center"><a href="#"
class="author d-flex align-items-center flex-wrap">
<div class="avatar"><img src="{{ post.author.avatar.url }}" alt="..." class="img-fluid"></div>
<div class="title"><span>{{ post.author }}</span></div>
</a>
<div class="comments meta-last"><i class="icon-comment"></i>{{ post.get_comment_number }}</div>
</div>
</div>
</div>
{% endfor %}
</div>
<!-- Pagination -->
</div>
</main>
{% include 'sidebar.html' with common_tags=common_tags latest_posts=latest_posts %}
</div>
</div>
{% endblock content %}
This is a django related question:
I am doing an assignment where we are playing around making a search bar then afterwards letting each individual search result linked to its own page with more details. In this context we are doing a job search engine and I need assistance in when you click each jobs posting, it takes you to a separate page with more info about the job. We already made templates for all the pages. I understand that we have to make a request to the api again after doing it for the view function in the search bar and also use templating got fill up out the detailed search results.Im just not sure how would I apply these concepts to the html file that w ehave.
here's the code
View function code
import requests
from django.shortcuts import render
def home(request):
context = {
'example_context_variable': 'Change me.',
}
return render(request, 'pages/home.html', context)
def search_results(request):
search_query = request.GET['searchterm']
context = {
'result_count': 0,
'search_term': search_query,
}
context['results_count'] = 0
url = 'https://jobs.github.com/positions.json?location=bay+area&description='
url += search_query
response = requests.get(url)
results_data = response.json()
job_list =[]
for result in results_data:
job_list.append(result)
context['job_results'] = job_list
return render(request, 'pages/search_results.html', context)
Search Results Page
{% extends "base.html" %}
{% block title %}
Search Results
{% endblock title %}
{% block additional_styles %}
<style>
body {
background-color: white;
}
</style>
{% endblock %}
{% block content %}
<div id="home-content" class="container">
<div class="row">
<div class="col-lg-3"></div> <!-- Column for spacing -->
<div class="col-lg-6">
<div class="mt-5 mb-3 text-center">
<h1>Search Results</h1>
</div>
<form method="GET" action="/search-results/">
<div class="input-group mb-2">
<input name="searchterm" type="text" class="form-control form-control-lg" placeholder="Let's find a job..." />
<div class="input-group-append">
<button class="btn btn-primary btn-lg">Search</button></a>
</div>
</div>
</form>
<!-- 2start -->
<p>You Searched for: {{search_term}}</p>
{% for job in job_results %}
<div class="list-group">
<a href="/detailed-search-results/" class="list-group-item list-group-item-action flex-column align-items-start">
<div class="d-flex w-100 justify-content-between">
<h5 class="mb-1">{{job.title}}</h5>
</div>
<div>
<small class="text-muted">{{job.location}}</small>
</div>
</a>
</div>
<br>
{% endfor %}
<!-- End -->
{% endblock content %}
**detailed Search Results Html file **
So far when you click on a posting it takes you to the detailed search result page without anything on it.
That is because you have hyperlinked each job posting to /detailed-search-results/.
Looking at the API response, you need to change it to job.url
Replace your for loop with this:
{% for job in job_results %}
<div class="list-group">
<a href="{{ job.url }}" class="list-group-item list-group-item-action flex-column align-items-start">
<div class="d-flex w-100 justify-content-between">
<h5 class="mb-1">{{job.title}}</h5>
</div>
<div>
<small class="text-muted">{{job.location}}</small>
</div>
</a>
</div>
<br>
{% endfor %}
I'm learning programming and following a tutorial using django 3, the same I'm using.
The text and images are not displaying on the frontend on one particular html file.
1.-In settings.py I have this:
MEDIA_ROOT= os.path.join(BASE_DIR,"media")
MEDIA_URL= "/media/"
2.-In models.py:
class Property(models.Model):
title = models.CharField(max_length=200)
main_photo = models.ImageField(upload_to='photos/%Y/%m/%d/')
3.-In admin.py:
from django.contrib import admin
from .models import Property
class PropertyAdmin(admin.ModelAdmin):
list_display = ('id', 'title', 'is_published')
list_display_links = ('id', 'title')
search_fields = ('title', 'town')
list_editable = ('is_published',)
list_per_page = 30
admin.site.register(Property, PropertyAdmin)
Then I migrated to the DB, I created a properties.html and the loop {{ property.main_photo.url }} or {{ property.title }} is working and getting images and texts on this properties file:
{% extends 'base.html' %}
{% load humanize %}
{% block content %}
<section id="showcase-inner" class="py-5 text-white">
<div class="container">
<div class="row text-center">
<div class="col-md-12">
<h1 class="display-4">Browse Our Properties</h1>
<p class="lead">Lorem ipsum dolor sit, amet consectetur adipisicing elit. Sunt, pariatur!</p>
</div>
</div>
</div>
</section>
<!-- Listings -->
<section id="listings" class="py-4">
<div class="container">
<div class="row">
{% if properties %}
{% for property in properties %}
<div class="col-md-6 col-lg-4 mb-4">
<div class="card listing-preview">
<img class="card-img-top" src="{{ property.main_photo.url }}" alt="">
<div class="card-img-overlay">
<h2>
<span class="badge badge-secondary text-white">From {{ property.price_per_week | intcomma }}€ per week</span>
</h2>
</div>
<div class="card-body">
<div class="listing-heading text-center">
<h4 class="text-primary">{{ property.title }}</h4>
<p>
<i class="fas fa-map-marker text-secondary"></i> {{ property.town }}</p>
</div>
<hr>
<div class="row py-2 text-secondary">
<div class="col-6">
<i class="fas fa-check"></i> {{ property.swimming_pool }}</div>
<div class="col-6">
<i class="fas fa-wifi"></i> {{ property.free_wifi }}</div>
</div>
<div class="row py-2 text-secondary">
<div class="col-6">
<i class="fas fa-bed"></i> Bedrooms: {{ property.bedrooms }}</div>
<div class="col-6">
<i class="fas fa-bath"></i> Bathrooms: {{ property.bathrooms }}</div>
</div>
More Info
</div>
</div>
</div>
{% endfor %}
{% else %}
<div class="col-md-12">
<p>No Properties available</p>
</div>
{% endif %}
</div>
<div class="row">
<div class="col-md-12">
{% if properties.has_other_pages %}
<ul class="pagination">
{% if properties.has_previous %}
<li class="page-item">
<a href="?page={{properties.previous_page_number}}" class="page-link">«
</a>
</li>
{% else %}
<li class="page-item-disabled">
<a class="page-link">«</a>
</li>
{% endif %}
{% for i in properties.paginator.page_range %}
{% if properties.number == i %}
<li class="page-item active">
<a class="page-link">{{i}}</a>
</li>
{% else %}
<li class="page-item">
{{i}}
</li>
{% endif %}
{% endfor %}
</ul>
{% endif %}
</div>
</div>
</div>
</section>
{% endblock %}
The next step is to create a property.html file and also use loop, but everything that uses the loop doble curly braces are not displaying:
{% extends 'base.html' %}
{% load humanize %}
{% block content %}
<section id="showcase-inner" class="py-5 text-white">
<div class="container">
<div class="row text-center">
<div class="col-md-12">
<h1 class="display-4">{{ property.title }}</h1>
<p class="lead">
<i class="fas fa-map-marker"></i> {{ property.town }}</p>
</div>
</div>
</div>
</section>
{% endblock %}
I checked multiple times and my code is exactly like on the tutorial but my frontend is not displaying.
Views.py:
from django.shortcuts import get_object_or_404, render
from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator
from .models import Property
def index(request):
properties = Property.objects.get_queryset().order_by('id').filter(is_published=True)
paginator = Paginator(properties, 30)
page = request.GET.get('page')
paged_properties = paginator.get_page(page)
context = {
'properties': paged_properties
}
return render(request, 'properties/properties.html', context)
def property(request, property_id):
property = get_object_or_404(Property, pk=property_id)
context = {
'property': property
}
return render(request, 'properties/property.html')
def search(request):
return render(request, 'properties/search.html')
You are not passing the context to properties/property.html inside def property(..., ...)
Change:
return render(request, 'properties/property.html')
To:
return render(request, 'properties/property.html', context)
The voting proceess is working fine with this code. The problem is only when redirecting after voting the options.
Exception Type:DoesNotExist
Exception Value:
Category matching query does not exist.
category = Category.objects.get(slug=slug)
urls.py
path('<slug>/',views.options,name='options'),
path('<slug>/vote/', views.vote, name='vote'),
views.py
def home(request):
categories = Category.objects.filter(active=True)
return render(request,'rank/base.html',{'categories': categories,'title':'TheRanker'})
def options(request,slug):
category = Category.objects.get(slug=slug)
options = Option.objects.filter(category=category)
return render(request,'rank/options.html',{'options':options,'title':'options'})
def vote(request,slug):
option = Option.objects.get(slug=slug)
if Vote.objects.filter(slug=slug,voter_id=request.user.id).exists():
messages.error(request,'You Already Voted!')
return redirect('rank:options',slug)
else:
option.votes += 1
option.save()
voter = Vote(voter=request.user,option=option)
voter.save()
messages.success(request,'Voted!')
return redirect('rank:options',slug)
options.html
{% extends "rank/base.html" %}
<title>{% block title %}{{title}}{% endblock title%}</title>
{% load bootstrap4 %}
{% block content %}
<center><br>
<center>{% bootstrap_messages %}</center>
<ol type="1">
{% for option in options %}
<div class="col-lg-6 col-md-6 mb-6">
<div class="card h-100">
<div class="card-body">
<b><li>
<img src="/media/{{option.image}}" width="200" height="100">
<h4>{{option.name}}
</h4>
<h5 class="card-text">{{ option.details}}</h5>
<h5>{{ option.votes }} votes</h5>
<form action="{% url 'rank:vote' option.slug %}" method="post">
{% csrf_token %}
<input type="submit" class="btn btn-success" value="Vote" >
</form>
</li></b>
</div>
<div class="card-footer">
<small class="text-muted"></small>
</div>
</div>
</div>
{% endfor %}
</ol>
</center>
{% endblock content%}
You're confusing categories and options. The form sends the slug of the option, but then you redirect to the categories view using the same slug. But those are two different models.