Django :NoReverseMatch at /spacemissions/organisation/2/ - django

I am getting the following error when, from the list view, I try to access the detail view.
Error screenshot
The odd thing is that some of the detail views work, some not, and I do not understand where is the problem. For example, here's the detail view of the organisation with pk=1
organisation detail view
Organisation model
class Organisation(models.Model):
code = models.CharField(max_length=256, unique=True)
name = models.CharField(max_length=256, null=True)
english_name = models.CharField(max_length=256, null=True)
location = models.CharField(max_length=256, null=True)
country = models.ForeignKey('space_missions.Country',
on_delete=models.SET_NULL, null=True, blank=True)
longitude = models.FloatField(null=True)
latitude = models.FloatField(null=True)
parent_organisation = models.ForeignKey('self', on_delete=models.SET_NULL, null=True, blank=True)
Views
class OrganisationDetail(generic.DetailView):
model = models.Organisation
class OrganisationList(generic.ListView):
model = models.Organisation
organisation_list.html
{% extends 'base.html' %}
{% block content %}
<h1>Organisation List</h1>
{% if organisation_list %}
<ul>
{% for organisation in organisation_list %}
<li>
<a href="{% url 'space_missions:organisation-detail' pk=organisation.pk %}">
{{ organisation.name }}
</a>
</li>
{% endfor %}
</ul>
{% else %}
<p>No organisation is stored in the database!</p>
{% endif %}
{% endblock %}
organisation_detail.html
{% extends 'base.html' %}
{% block content %}
<div class="container">
<h1>{{ organisation.name }}'s details:</h1>
<ul>
<li><strong>Code: </strong> {{ organisation.code }}</li>
<li><strong>English Name: </strong> {{ organisation.english_name }}</li>
<li><strong>Location: </strong> {{ organisation.location }}</li>
<li><strong>Country: </strong>
<a href="{% url 'space_missions:country-detail' pk=organisation.country_id %}">
{{ organisation.country.name }}
</a>
</li>
<li><strong>Longitude: </strong> {{ organisation.longitude }}</li>
<li><strong>Latitude: </strong> {{ organisation.latitude }}</li>
<li>
<strong>Parent organisation: </strong>
<a href="{% url 'space_missions:organisation-detail' pk=organisation.parent_organisation_id %}">
{{ organisation.parent_organisation.name }}
</a>
</li>
</ul>
</div>
{% endblock %}
urls.py
from django.urls import path
from . import views
app_name = 'space_missions'
urlpatterns = [
path('countries/', views.CountryList.as_view(), name='countries'),
path('country/<int:pk>/', views.CountryDetail.as_view(), name='country-detail'),
path('astronauts/', views.AstronautList.as_view(), name='astronauts'),
path('astronaut/<int:pk>/', views.AstronautDetail.as_view(), name='astronaut-detail'),
path('organisations/', views.OrganisationList.as_view(), name='organisations'),
path('organisation/<int:pk>/', views.OrganisationDetail.as_view(), name='organisation-detail'),
path('engines/', views.EngineList.as_view(), name='engines'),
path('engine/<int:pk>/', views.EngineDetail.as_view(), name='engine-detail'),
path('stages/', views.StageList.as_view(), name='stages'),
path('stage/<int:pk>/', views.StageDetail.as_view(), name='stage-detail'),
path('launchvehicles/', views.LaunchVehicleList.as_view(), name='launch-vehicles'),
path('launchvehicle/<int:pk>/', views.LaunchVehicleDetail.as_view(), name='launch-vehicle-detail'),
path('missions/', views.MissionList.as_view(), name='missions'),
path('mission/<int:pk>/', views.MissionDetail.as_view(), name='mission-detail'),
path('selections/', views.SelectionList.as_view(), name='selections'),
path('selection/<int:pk>/', views.SelectionDetail.as_view(), name='selection-detail')
]

When parent_organisation is None then your detail page can not find url of organisation-detail with pk=None
<a href="{% url 'space_missions:organisation-detail' pk=organisation.parent_organisation_id %}">
{{ organisation.parent_organisation.name }}
</a>
Wrap your code with if block
{% if organisation.parent_organisation_id %}
<a href="{% url 'space_missions:organisation-detail' pk=organisation.parent_organisation_id %}">
{{ organisation.parent_organisation.name }}
</a>
{% endif %}

Related

Django primary key url issues

I am makeing a simple blog project. In my project, there is one page where there is a list of all the blog posts. If you click on the title of the post you are taken to the post. I used (?P\d+) I the URL path so the user would be directed to the correct post. However, this did not work. Any help would be much appreciated.
all_posts.html
{% extends "base.html" %}
{% block content %}
<div class="container">
<h1>Blog Posts</h1>
</div>
<div class="container">
{% for blog_post in object_list %}
<table class="table table-striped">
<ul class="list-group">
<li><a class="btn btn-primary" href="{% url 'blog_app:view' pk=blog_post.pk %}">{{ blog_post.post_title }}</a></li>
</ul>
</table>
{% endfor %}
</div>
{% endblock %}
modles.py
from django.db import models
# Create your models here.
class Blog_Post(models.Model):
slug = models.SlugField(max_length=1000, editable=False, null=True)
post_title = models.CharField(max_length=100, editable=True, blank=False, null=True)
blog_content = models.TextField(max_length=10000, blank=False, editable=True, null=True)
files = models.FileField(blank=True, null=True, upload_to=True)
date = models.DateTimeField(blank=False, null=True, auto_now=True, editable=False)
likes = models.IntegerField(blank=True, null=True, editable=False)
urls.py
from django.urls import path
from . import views
app_name = "blog_app"
urlpatterns = [
path('create/', views.create_blog_post.as_view(), name='create'),
path('view/(?P<pk>\d+)/', views.view_blog_post.as_view(), name='view'),
path('all_posts/', views.all_blog_posts.as_view(), name='all'),
path('delete/<slug:slug>', views.delet_blog_post.as_view(), name='delete')
]
path is for converters like slug, str, int, to work with regex you need re_path
you can just redefine it as "view/<int:pk>/"
{% extends "base.html" %}
{% block content %}
<div class="container">
<h1>Blog Posts</h1>
</div>
<div class="container">
{% for blog_post in object_list %}
<table class="table table-striped">
<ul class="list-group">
<li><a class="btn btn-primary" href="{% url 'blog_app:view' pk=blog_post.pk %}">{{ blog_post.post_title }}</a></li>
</ul>
</table>
{% endfor %}
</div>
{% endblock %}
i think the problem is in this line
<li><a class="btn btn-primary" href="{% url 'blog_app:view' pk=blog_post.pk %}">
when you send data in url tag you don't assign it to prametars ,
the right line will be this :
<li><a class="btn btn-primary" href="{% url 'blog_app:view' blog_post.pk %}">

Only Show Edit Button On Owner's Posts - Django

I have a Django project with posts and the ability to edit posts.
On the main index page, I am showing all posts, like a news feed.
Currently anyone can edit any post, but I want to make it so that only the owner of the post can edit. I'm just not sure how to write the urls.py file since I'm using:
path("", views.index, name="index"),
I would probably need to pass either the post id or the username to this, but I'm not sure how to write it. I tried:
path("index", views.index, name="index"),
path("index/<str:pk>", views.index, name="index"),
path("index/<str:username>", views.index, name="index"),
But I get errors.
views.py
def index(request):
list_of_posts = Post.objects.all().order_by('id').reverse()
paginator = Paginator(list_of_posts, 10)
num = request.GET.get('page', 1)
get_page_num = paginator.get_page(num)
return render(request, "network/index.html", {
"list_of_posts": list_of_posts,
"get_page_num": get_page_num,
})
models.py
class User(AbstractUser):
pass
class Post(models.Model):
text = models.TextField(max_length=500, blank=True,
null=True)
username = models.ForeignKey('User',
on_delete=models.CASCADE, related_name='author',
null=True, blank=True)
timestamp = models.DateTimeField(auto_now_add=True)
like = models.ManyToManyField(
User, blank=True, related_name="liked_user")
def __str__(self):
return self.username.username
html to show edit button. I've tried:
{% if post.username == request.user.username %}
<button class="btn-btn primary" my-id="{{i.id}}" id="ebutton-
{{i.id}}" onclick="edit_form(this)" >Edit</button>
<br><br><br>
{% endif %}
Full html of this page:
{% extends "network/layout.html" %}
{% load static %}
{% block body %}
<br>
<h3> <center> Welcome. Here is your news feed: </center> </h3>
<br>
{% for i in get_page_num %}
<div class='card mb-3' style="max-width: 530px;" id="card-posts">
<div class="row no-gutters">
<div class="col-md-8">
<div class="card-body">
<h5 class="card-title"><a href="{% url 'profile'
username=i.username %}">{{i.username}}</a></h5>
<span id="textinfo-{{i.id}}"
class="post">{{i.text}}</span> <br>
<textarea my-id="{{i.id}}" id="edit-me-{{i.id}}"
style="display:none;" class="form-control
textarea" row="3">{{i.text}}</textarea>
<br>
<p class="card-text">{{i.timestamp}}</p>
<div class="like mt-1">
<img my-id="{{i.id}}" id="is-it-liked-{{i.id}}"
class="like-class"
{% if not request.user in i.like.all %}
clicked="no"
src="https://img.icons8.com/emoji/452/white-heart.png"
{%else%}
clicked="yes"
src="https://img.icons8.com/emoji/452/red-heart.png"
{%endif%}
/> <span id="post-count-{{i.id}}">{{i.like.count}}.
</span>
</div>
<br>
{% if request.user == post.username %}
<button class="btn-btn primary" my-id="{{i.id}}"
id="ebutton-{{i.id}}" onclick="edit_form(this)"
>Edit</button>
<br><br><br>
{% endif %}
</div>
</div>
</div>
</div>
{% endfor %}
<br><br>
<div class="pagination">
<span class="step-links">
{% if get_page_num.has_previous %}
<a href="?page={{ get_page_num.previous_page_number }}"
class="page-link">Previous</a>
{% else %}
<li class="page-item disabled"><a class="page-
link">Previous</a></li>
{% endif %}
{% if get_page_num.has_next %}
<a href="?page={{ get_page_num.next_page_number }}" class="page-
link">Next</a>
{% else %}
<a class="page-link">Next</a>
{% endif %}
</span>
</div>
{% endblock %}
{% block script %} <script src="{% static
'network/network.js'%}"></script> {% endblock %}
With this way I need to pass username to the url but I cannot, without getting errors.
Overall I'm just looking for advice, on how to make the edit button only appear on posts that the current user is an owner on. So that way no one can edit anyone else's posts.
If you want to show all posts and only allow a post author to edit it, you need to inject all posts and the request user in your template context. Then in your template iterate through the posts and check if the author is equal to the request user before showing the edit button. But first you need a foreign key in your post model that refers to the author.
Urls.py
urlpatterns = [path("index/", views.index, name="index")]
Views
def index(request):
list_of_posts = Post.objects.order_by('-id')
request_user = request.user
return render(request, "network/index.html", {
"list_of_posts": list_of_posts,
"request_user": request_user
})
Models
class Post(models.Model):
user = models.ForeignKey(User, on_delete=models.PROTECT, related_name='posts')
# Other fields
Template
{% if post.user == request_user %}
<!--Show the edit button-->
{% endif %}
You can also access directly the request object in your template:
{% if post.user == request.user %}
<!--Show the edit button-->
{% endif %}
I needed to add
{% if request.user == i.username %}
because I was looping in the html page, for i in get_page_num:. I did not previously have the i.
{% if request.user == post.author %}
<button>Delete</button>
{% endif %}
This assumes that you have a Post model with an attribute of author

Can't add normal Comment section in my Django web-application

I have trouble with adding comments to my django web-application. I want to add comments to allow users comment posts, like in normal web blog. I've tried a few ways, but nothing worked correctly for me.
After a few weeks searching and trying different ways to solve this question, I've stacked on this question. I have some progress, but it's now what I want completely.
Now I can only add "comments" from admin panel
and it look like this (from admin panel)
and like this (from user interface)
And I have this issue with padding comments( I don't really understand why it's occurs ¯_(ツ)_/¯ )
Anyway, here is my code, hope someone know how to solve this problem:
models.py
class Comment(models.Model):
post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='comments')
author = models.ForeignKey(User, on_delete=models.CASCADE)
text = models.TextField()
created_date = models.DateField(auto_now_add=True)
def __str__(self):
return self.text
...
class Post(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
categories = models.ManyToManyField('Category', related_name='posts')
image = models.ImageField(upload_to='images/', default="images/None/no-img.jpg")
slug= models.SlugField(max_length=500, unique=True, null=True, blank=True)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('post-detail', kwargs={'slug': self.slug})
post_detail.html
<article class="media content-section">
{% for comment in post.comments.all %}
<ul>
{{ comment.text }}
{% for reply in comment.replies.all %}
<li>
{{ reply.text }}
</li>
{% endfor %}
<ul>
{% endfor %}
</article>
I also read this article about creation blog for beginners, and they have working comment section as I want, but I tried to implement their code to my web-app, and nothing worked for me.
They have comment section like this (I need completely the same one):
But when I tried to follow their tutorial, I have only like this:
And here is the code for this unsuccessful solution( but I feel like it is working one, maybe I did something wrong)
post_detail.html
{% extends 'blog/base.html' %}
{% block content %}
<article class="media content-section">
<img class="rounded-circle article-img" src="{{ object.author.profile.image.url }}" alt="">
<div class="article-metadata">
<a class="mr-2 author_title" href="{% url 'user-posts' object.author.username %}">#{{ object.author }}</a>
<small class="text-muted">{{ object.date_posted|date:"N d, Y" }}</small>
<div>
<!-- category section -->
<small class="text-muted">
Categories:
{% for category in post.categories.all %}
<a href="{% url 'blog_category' category.name %}">
{{ category.name }}
</a>
{% endfor %}
</small>
</div>
{% if object.author == user %}
<div>
<a class='btn btn-secondary btn-sm mt-1 mb-1' href="{% url 'post-update' object.slug %}">Update</a>
<a class='btn btn-danger btn-sm mt-1 mb-1' href="{% url 'post-delete' object.slug %}">Delete</a>
</div>
{% endif %}
</div>
</article>
<article class="media content-section">
<div class="media-body">
<img class="img-fluid center" id="rcorners3" src="{{ object.image.url }}" alt="none">
<h2 class="article-title text-center">{{ object.title }}</h2>
<p class="article-content">{{ object.content }}</p>
</div>
</article>
<article class="media content-section">
<form action="/blog/{{ post.pk }}/" method="post">
{% csrf_token %}
<div class="form-group">
{{ form.author }}
</div>
<div class="form-group">
{{ form.body }}
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
<h3>Comments:</h3>
{% for comment in comments %}
<p>
On {{comment.created_on.date }}
<b>{{ comment.author }}</b> wrote:
</p>
<p>{{ comment.body }}</p>
<hr>
{% endfor %}
</article>
{% endblock content %}
views.py
...
def comment(request):
if request.method == 'POST':
form = CommentForm(request.POST)
if form.is_valid():
comment = Comment(
author=form.cleaned_data["author"],
body=form.cleaned_data["body"],
post=post
)
comment.save()
comments = Comment.objects.filter(post=post)
context = {
"post": post,
"comments": comments,
"form": form,
}
models.py
...
class Comment(models.Model):
post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='comments')
author = models.ForeignKey(User, on_delete=models.CASCADE)
text = models.TextField()
created_date = models.DateField(auto_now_add=True)
def __str__(self):
return self.text
forms.py
from django import forms
class CommentForm(forms.Form):
author = forms.CharField(
max_length=60,
widget=forms.TextInput(attrs={
"class": "form-control",
"placeholder": "Your Name"
})
)
body = forms.CharField(widget=forms.Textarea(
attrs={
"class": "form-control",
"placeholder": "Leave a comment!"
})
)
You are creating unnecessary lists. Try this one
<article class="media content-section">
<ul>
{% for comment in post.comments.all %}
<li>{{ comment.text }}</li>
{% if comment.replies.all %}
<ul>
{% for reply in comment.replies.all %}
<li>{{ reply.text }}</li>
{% endfor %}
</ul>
{% endif %}
{% endfor %}
<ul>
</article>

filter in django 2.0

Hey I am writing app in django many blogs with many articles each but i dont know how to take artices which belongs to blog and write filter
My articles model
class Articles(models.Model):
title = models.CharField(max_length=150, verbose_name="Tytul")
content = models.TextField(verbose_name="Tekst")
published = models.DateTimeField(verbose_name="Data publikacji",auto_now=True)
image = models.FileField(upload_to="images",verbose_name="Obrazy",default=None)
blog = models.ForeignKey(Blogs,on_delete=models.CASCADE,null=True)
My blogs model
class Blogs(models.Model):
title = models.CharField(max_length=150, verbose_name="Tytul")
user = models.CharField(max_length=160, verbose_name="Uzytkownik")
blog.html
{% include 'base.html' %}
{% block blog %}
<h2>{{ blog.title }}</h2>
<div class="blog-info">
Tworca : {{ blog.user }}
</div>
{% block article %}
{% for a in article.blog_set.all %} <---- here
<div class="article">
Opublikowano : {{ a.published }}
</div>
<img src="{{ a.image.url }}" class="article-img">
<div class="article-intro">
<p>{{ a.content }}</p>
</div>
{% endfor %}
{% endblock %}
{% endblock %}
database

Other templates are not inheriting FOR LOOP in my base template

The loop is actually for the Navigation. Listing Categories and Shops who sells or render services under each category.
Please.. I'm new to Django and Python. And i'm sorry if i'm very slow to getting this things... Thanks
models.py
class ShopCategories(models.Model):
category = models.CharField(max_length=50, unique=True)
def __str__(self):
return self.category
class NewShop(models.Model):
category = models.ForeignKey(ShopCategories)
main_image = models.FileField(null=True, blank=True)
name = models.CharField(max_length=100, unique=True)
tagline = models.CharField(max_length=50, default='Enter tagline here2')
description = models.TextField(default='enter shop description')
shop_image = models.FileField(null=True, blank=True)
views.py
def homepage(request):
return render_to_response('index.html')
def basefile(request):
cat1 = NewShop.objects.filter(category_id=1)
cat2 = NewShop.objects.filter(category_id=2)
cat3 = NewShop.objects.filter(category_id=3)
cat4 = NewShop.objects.filter(category_id=4)
name1 = ShopCategories.objects.filter(id=1)
name2 = ShopCategories.objects.filter(id=2)
name3 = ShopCategories.objects.filter(id=3)
name4 = ShopCategories.objects.filter(id=4)
return render_to_response('base.html', {'Shop_cat1':cat1, 'Shop_cat2':cat2, 'Shop_cat3':cat3,
'Shop_cat4':cat4,'shop_name1':name1, 'shop_name2':name2,
'shop_name3':name3, 'shop_name4':name4})
base.html
<ul class="nav navbar-nav">
<li class="current-menu-item">
<ul class="nav navbar-nav">
<li class="current-menu-item">
ENTOURAGE MALL
</li>
<li class="dropdown pi-mega-fw menu-item-has-children">
SHOPS
<ul class="dropdown-menu">
<li>
<div class="pi-mega-content">
<div class="row">
<div class="col-md-3 pi-mm-col">
<ul class="pi-mm-list">
{% for shop in shop_name1 %}
<li>
<h3> {{ shop }}</h3>
</li>
{% endfor %}
{% for cat in Shop_cat1 %}
<li>{{ cat }}</li>
{% endfor %}
</ul>
</div>
<div class="col-md-3 pi-mm-col">
<ul class="pi-mm-list">
{% for shop in shop_name2 %}
<li>
<h3> {{ shop }}</h3>
</li>
{% endfor %}
{% for cat in Shop_cat2 %}
<li>{{ cat }}</li>
{% endfor %}
</ul>
</div>
<div class="col-md-3 pi-mm-col">
<ul class="pi-mm-list">
{% for shop in shop_name3 %}
<li>
<h3> {{ shop }}</h3>
</li>
{% endfor %}
{% for cat in Shop_cat3 %}
<li>{{ cat }}</li>
{% endfor %}
</ul>
</div>
</div>
</div>
</li>
</ul>
</li>
<li class="menu-item">
ENTOURAGE LOUNGE
</li>
<li class="menu-item">
About MALL
</li>
<li class="menu-item">
BLOG
</li>
</ul>
index.html
{% extends "base.html" %}
{% block title %} This is Homepage {% endblock title %}
Urls.py
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^$', views.homepage),
url(r'^base/', views.basefile)
]
if settings.DEBUG:
urlpatterns += static(settings.STATIC_URL, document_root= settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, docuemt_root= settings.MEDIA_ROOT)
It works just fine in base.html. But when i {% extends base.html %} in index or other templates. The templates loads just fine, but the FOR loop isnt functional. What exactly am i doing wrong?
You should provide context in homepage view in the same way as in basefile view:
def homepage(request):
cat1 = NewShop.objects.filter(category_id=1)
cat2 = NewShop.objects.filter(category_id=2)
cat3 = NewShop.objects.filter(category_id=3)
cat4 = NewShop.objects.filter(category_id=4)
name1 = ShopCategories.objects.filter(id=1)
name2 = ShopCategories.objects.filter(id=2)
name3 = ShopCategories.objects.filter(id=3)
name4 = ShopCategories.objects.filter(id=4)
return render_to_response('index.html', {'Shop_cat1':cat1, 'Shop_cat2':cat2, 'Shop_cat3':cat3,
'Shop_cat4':cat4,'shop_name1':name1, 'shop_name2':name2,
'shop_name3':name3, 'shop_name4':name4})