I had this error before but I couldn't fix it, so I moved back to previous git state. Now I have to fix this, why does this error keep happening? And what does this even mean? It's occuring from index.html {% url vote_for_post %} Here's my code, thanks in advance.
views.py
def index(request):
categories = Category.objects.order_by('likes')
latest_posts = list(Post.objects.order_by('pub_date')[:50])
hot_posts = sorted(latest_posts, key=lambda x: x.hot(), reverse=True)
controversial_topics = sorted(latest_posts, key=lambda x: x.controversy(), reverse=True)
context_dict = {
'latest_posts': latest_posts,
'categories': categories,
'hot_posts': hot_posts,
'controversial_topics':controversial_topics
}
return render(request, 'main/index.html', context_dict)
def vote_for_post(request, category_name, post_id):
category = get_object_or_404(Category, name=category_name)
post = get_object_or_404(Post, id=post_id, category=category)
if request.POST['type'] == 'upvote':
post.upvotes += 1
if request.POST['type'] == 'downvote':
post.downvotes += 1
post.save()
if request.POST['referer'] == 'index':
return HttpResponseRedirect(reverse('main:index'))
if request.POST['referer'] == 'category':
return HttpResponseRedirect(reverse('main:category', args=(category.name,)))
urls.py
urlpatterns = [
url(r'^$', views.index, name='index'),
#url(r'^add_post/', views.add_post, name='add_post'),
url(r'^add_post/$', PostCreateView.as_view(), name='post-add'),
url(r'^vote/$', views.vote_for_post, name='vote_for_post'),
url(r'^(?P<slug>[\w|\-]+)/edit/$', PostUpdateView.as_view(), name='post-edit'),
url(r'^(?P<slug>[\w|\-]+)/delete/$', PostDeleteView.as_view(), name='post-delete'),
url(r'^add_category/', views.add_category, name='add_category'),
url(r'^(?P<slug>[\w|\-]+)/$', views.post, name='post'),
url(r'^category/(?P<category_name_slug>[\w\-]+)/$', views.category, name='category'),
]
index.html
<div class="row placeholders">
<div class="col-sm-8">
<div class="row">
{% if hot_posts %}
{% for vote in hot_posts %}
<article>
<div class="vote">
<form method="post" style="display: inline"
action="{% url vote_for_post %}">
<input type="hidden" value="upvote" name="type">
<input type="hidden" value="index_page" name="referer">
<button type="submit">+</button>
{% csrf_token %}
</form>
<form method="post" style="display: inline"
action="{% url 'main:vote' vote.category.name vote.id %}">
<input type="hidden" value="downvote" name="type">
<input type="hidden" value="index_page" name="referer">
<button type="submit">-</button>
{% csrf_token %}
</form>
</div>
</article>
<hr>
{% endfor %}
{% else %}
<p>No topics are available.</p>
{% endif %}
</div>
</div>
</div>
As I see, "add_post", "vote" and "add_category" are ambiguous with your "slug" due to regex match.
url(r'^(?P<slug>[\w|\-]+)/$', views.post, name='post'),
url(r'^vote/$', views.vote_for_post, name='vote_for_post'),
url(r'^add_post/$', PostCreateView.as_view(), name='post-add'),
url(r'^add_category/', views.add_category, name='add_category'),
Try to give a better identifier for your urls.
e.g.
url(r'^(?P<slug>[\w|\-]+)/$', views.post, name='post'),
url(r'^vote/post/$', views.vote_for_post, name='vote_for_post'),
url(r'^add/post/$', PostCreateView.as_view(), name='post-add'),
url(r'^add/category/$', views.add_category, name='add_category'),
Let me know if this helped.
From the Django documentation: https://docs.djangoproject.com/en/1.9/ref/templates/builtins/#url
{% url 'some-url-name' v1 v2 %}
In your code you should add ' ' to the name in the url template tag.
<form method="post" style="display: inline" action="{% url vote_for_post %}">
should be:
<form method="post" style="display: inline" action="{% url 'vote_for_post' %}">
Concerning the NoReverseMatch at / u'main' is not a registered namespace.
Remove the 'main:' in your (reverse('main:index')) and reverse('category', args=(category.name,)) in your views.py
if request.POST['referer'] == 'index':
return HttpResponseRedirect(reverse('index'))
if request.POST['referer'] == 'category':
return HttpResponseRedirect(reverse('category', args=(category.name,)))
Related
After I posted my comment and decided to refresh the page it adds the same comment over and over on every refresh how can I stop this?
The code for the comment review is at the far bottom in the template.html.
And the review code is under "def product_detail" in the views.py.
Can someone give me some tips so if I refresh it dosen't do another post?
template file:
{% extends "base.html" %}
{% load static %}
{% block page_header %}
<div class="container header-container">
<div class="row">
<div class="col"></div>
</div>
</div>
{% endblock %}
{% block content %}
<div class="overlay"></div>
<div class="container-fluid">
<div class="row">
<div class="col-12 col-md-6 col-lg-4 offset-lg-2">
<div class="image-container my-5">
{% if product.image %}
<a href="{{ product.image.url }}" target="_blank">
<img class="card-img-top img-fluid" src="{{ product.image.url }}" alt="{{ product.name }}">
</a>
{% else %}
<a href="">
<img class="card-img-top img-fluid" src="{{ MEDIA_URL }}noimage.png" alt="{{ product.name }}">
</a>
{% endif %}
</div>
</div>
<div class="col-12 col-md-6 col-lg-4">
<div class="product-details-container mb-5 mt-md-5">
<p class="mb-0">{{ product.name }}</p>
<p class="lead mb-0 text-left font-weight-bold">${{ product.price }}</p>
{% if product.category %}
<p class="small mt-1 mb-0">
<a class="text-muted" href="{% url 'products' %}?category={{ product.category.name }}">
<i class="fas fa-tag mr-1"></i>{{ product.category.friendly_name }}
</a>
</p>
{% endif %}
{% if product.get_rating > 0 %}
<small class="text-muted"><i class="fas fa-star mr-1"></i>{{ product.get_rating }} / 5</small>
{% else %}
<small class="text-muted">No Rating</small>
{% endif %}
{% if request.user.is_superuser %}
<small class="ml-3">
Edit |
<a class="text-danger" href="{% url 'delete_product' product.id %}">Delete</a>
</small>
{% endif %}
<p class="mt-3">{{ product.description }}</p>
<form class="form" action="{% url 'add_to_bag' product.id %}" method="POST">
{% csrf_token %}
<div class="form-row">
{% with product.has_sizes as s %}
{% if s %}
<div class="col-12">
<p><strong>Size:</strong></p>
<select class="form-control rounded-0 w-50" name="product_size" id='id_product_size'>
<option value="xs">XS</option>
<option value="s">S</option>
<option value="m" selected>M</option>
<option value="l">L</option>
<option value="xl">XL</option>
</select>
</div>
{% endif %}
<div class="col-12">
<p class="mt-3"><strong>Quantity:</strong></p>
<div class="form-group w-50">
<div class="input-group">
<div class="input-group-prepend">
<button class="decrement-qty btn btn-black rounded-0"
data-item_id="{{ product.id }}" id="decrement-qty_{{ product.id }}">
<span class="icon">
<i class="fas fa-minus"></i>
</span>
</button>
</div>
<input class="form-control qty_input" type="number"
name="quantity" value="1" min="1" max="99"
data-item_id="{{ product.id }}"
id="id_qty_{{ product.id }}">
<div class="input-group-append">
<button class="increment-qty btn btn-black rounded-0"
data-item_id="{{ product.id }}" id="increment-qty_{{ product.id }}">
<span class="icon">
<i class="fas fa-plus"></i>
</span>
</button>
</div>
</div>
</div>
</div>
<div class="col{% if s %}-12 mt-2{% endif %}">
<a href="{% url 'products' %}" class="btn btn-outline-black rounded-0 mt-5">
<span class="icon">
<i class="fas fa-chevron-left"></i>
</span>
<span class="text-uppercase">Keep Shopping</span>
</a>
<input type="submit" class="btn btn-black rounded-0 text-uppercase mt-5" value="Add to Bag">
</div>
<input type="hidden" name="redirect_url" value="{{ request.path }}">
{% endwith %}
</div>
</form>
</div>
</div>
</div>
<div class="w-full mt-6">
<h2 class="text-xl">Reviews</h2>
{% if request.user.is_authenticated %}
<form method="post" action="." class="mt-6 mb-6 p-6 bg-gray-100 rounded-xl">
{% csrf_token %}
<div>
<label>Rating</label><br>
<select class="form-control" name="rating">
<option value="1">1</option>
<option value="2">2</option>
<option value="3" selected>3</option>
<option value="4">4</option>
<option value="5">5</option>
</select>
</div>
<div class="form-group">
<label for="comment">Comment</label>
<textarea class="form-control" rows="5" id="comment" name="content"></textarea>
</div>
<button type="submit" class="btn btn-primary mb-2">Submit</button>
</form>
{% endif %}
{% for review in reviews %}
<div class="px-4 py-6 bg-gray-100 rounded-xl mb-4">
<strong>Author:</strong> {{ review.created_by }}<br>
<strong>Rating:</strong> {{ review.rating }}/5<br>
<strong>Date:</strong> {{ review.created_at|date:"Y-m-d" }}<br>
<strong>Comment:</strong><br>
{{ review.content }}
</div>
{% endfor %}
</div>
</div>
{% endblock %}
{% block postloadjs %}
{{ block.super }}
{% include 'products/includes/quantity_input_script.html' %}
{% endblock %}
views.py:
from django.shortcuts import render, redirect, reverse, get_object_or_404
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.db.models import Q
from django.db.models.functions import Lower
from .models import Product, Category, Review
from .forms import ProductForm
# Create your views here.
def all_products(request):
""" A view to show all products, including sorting and search queries """
products = Product.objects.all()
query = None
categories = None
sort = None
direction = None
if request.GET:
if 'sort' in request.GET:
sortkey = request.GET['sort']
sort = sortkey
if sortkey == 'name':
sortkey = 'lower_name'
products = products.annotate(lower_name=Lower('name'))
if sortkey == 'category':
sortkey = 'category__name'
if 'direction' in request.GET:
direction = request.GET['direction']
if direction == 'desc':
sortkey = f'-{sortkey}'
products = products.order_by(sortkey)
if 'category' in request.GET:
categories = request.GET['category'].split(',')
products = products.filter(category__name__in=categories)
categories = Category.objects.filter(name__in=categories)
if 'q' in request.GET:
query = request.GET['q']
if not query:
messages.error(request, "You didn't enter any search criteria!")
return redirect(reverse('products'))
queries = Q(name__icontains=query) | Q(description__icontains=query)
products = products.filter(queries)
current_sorting = f'{sort}_{direction}'
context = {
'products': products,
'search_term': query,
'current_categories': categories,
'current_sorting': current_sorting,
}
return render(request, 'products/products.html', context)
def product_detail(request, product_id):
""" A view to show individual product details """
product = get_object_or_404(Product, pk=product_id)
if request.method == 'POST':
rating = request.POST.get('rating', 3)
content = request.POST.get('content', '')
review = Review.objects.create(
product=product,
rating=rating,
content=content,
created_by=request.user
)
reviews = Review.objects.filter(product=product)
context = {
'product': product,
'reviews': reviews
}
return render(request, 'products/product_detail.html', context)
#login_required
def add_product(request):
""" Add a product to the store """
if not request.user.is_superuser:
messages.error(request, 'Sorry, only store owners can do that.')
return redirect(reverse('home'))
if request.method == 'POST':
form = ProductForm(request.POST, request.FILES)
if form.is_valid():
product = form.save()
messages.success(request, 'Successfully added product!')
return redirect(reverse('product_detail', args=[product.id]))
else:
messages.error(request, 'Failed to add product. Please ensure the form is valid.')
else:
form = ProductForm()
template = 'products/add_product.html'
context = {
'form': form,
}
return render(request, template, context)
#login_required
def edit_product(request, product_id):
""" Edit a product in the store """
if not request.user.is_superuser:
messages.error(request, 'Sorry, only store owners can do that.')
return redirect(reverse('home'))
product = get_object_or_404(Product, pk=product_id)
if request.method == 'POST':
form = ProductForm(request.POST, request.FILES, instance=product)
if form.is_valid():
form.save()
messages.success(request, 'Successfully updated product!')
return redirect(reverse('product_detail', args=[product.id]))
else:
messages.error(request, 'Failed to update product. Please ensure the form is valid.')
else:
form = ProductForm(instance=product)
messages.info(request, f'You are editing {product.name}')
template = 'products/edit_product.html'
context = {
'form': form,
'product': product,
}
return render(request, template, context)
#login_required
def delete_product(request, product_id):
""" Delete a product from the store """
if not request.user.is_superuser:
messages.error(request, 'Sorry, only store owners can do that.')
return redirect(reverse('home'))
product = get_object_or_404(Product, pk=product_id)
product.delete()
messages.success(request, 'Product deleted!')
return redirect(reverse('products'))
You should implement the Post/Redirect/Get architectural pattern [wiki], and thus return a redirect such that the browser will make a GET request next, and thus prevent making another POST request when refreshing the page:
def product_detail(request, product_id):
product = get_object_or_404(Product, pk=product_id)
if request.method == 'POST':
rating = request.POST.get('rating', 3)
content = request.POST.get('content', '')
Review.objects.create(
product=product,
rating=rating,
content=content,
created_by=request.user
)
# redirect to the same page đź–ź
return redirect('product_detail', product_id=product_id)
reviews = Review.objects.filter(product=product)
context = {
'product': product,
'reviews': reviews
}
return render(request, 'products/product_detail.html', context)
I tried to add new passenger and when I click on the button submit nothing happens, no error is thrown. I'm new in Django
urlpatterns = [
path("", views.index, name="index"),
path("<int:flight_id>", views.flight, name="flight"),
path("<int:flight_id>/book", views.book, name="book")
def flight(request, flight_id):
flight = Flight.objects.get(pk=flight_id)
return render(request, "flights/flight.html", {
"flight": flight,
"passengers": flight.passengers.all(),
"non_passengers": Passenger.objects.exclude(flights=flight).all()
def book(request, flight_id):
if request.method == "POST":
flight = Flight.objects.get(pk=flight_id)
passenger = Passenger.objects.get(pk=int(request.POST["passenger"]))
passenger.flights.add(flight)
return HttpResponseRedirect(reverse("flight", args=(flight.id)))
})
<form action="{% url 'book' flight.id %}" method="post">
{% csrf_token %}
<select name="passenger">
{% for passenger in non_passengers %}
<option value="{{ passenger.id }}">{{ passenger }}</option>
{% endfor %}
</select>
<input type="submit"
</form>
I've been learning Django for like a month so apologies if I'm doing something stupid, but, I'm getting a NoReverseMatch Reverse for 'profile' with arguments '('',)' not found. 1 pattern(s) tried: ['profile/(?P<use>[^/]+)$'] error when trying to render a "profile" page under the url '/profile/[a user's name]', and I'm pretty sure all my paths/patterns are correct?? Here's my code, could someone help me with this? All my other url patterns work fine. This path also worked fine before, I just renamed the "user" variable into "use" and this happened.
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("profile/<str:use>", views.profile, name="profile"),
path("following", views.following, name="following"),
#api
path('', include(router.urls)),
]
views.py:
def profile(request, use):
currentuser = str(request.user)
followers = []
following = []
for follow in Follow.objects.filter(following=use):
followers.append(follow.person)
for item in Follow.objects.filter(person=use):
following.append(item.following)
follower_count = len(followers)
following_count = len(following)
try:
Follow.objects.get(person=currentuser, following=use)
followed = True
except:
followed = False
post_list = Post.objects.filter(user=use)
dates = []
for post in post_list:
dates.append(post.timestamp)
dates.sort(key = lambda date: datetime.strptime(date, '%B %d, %Y, %I:%M %p'), reverse=True)
formattedlist = []
for date in dates:
postobject = Post.objects.get(timestamp=date)
formattedlist.append(postobject)
paginatorlist = Paginator(formattedlist, 10)
now_page_content = paginatorlist.page(1)
nowpage = 1
if request.method == "POST":
# Update the database
followbutton = request.POST.get("button")
button = request.POST.get("nav-button")
pagenum = request.POST.get("pg")
if followbutton:
if followbutton == "Follow":
followid = Follow.objects.all().count() + 1
person = currentuser
following = use
newfollow = Follow(followid, person, following)
newfollow.save()
return HttpResponseRedirect(f"/profile/{use}")
else:
deletefollow = Follow.objects.get(person=currentuser, following=use)
deletefollow.delete()
return HttpResponseRedirect(f"/profile/{use}")
else:
currentpage = paginatorlist.page(pagenum)
if button == 'Previous':
if pagenum == '1':
return render(request, "network/profile.html", {
"formattedlist": now_page_content, "currentnumber": nowpage, "message":'No previous page', "use": use, "currentuser": currentuser, "follower_count": follower_count, "following_count": following_count, "followed": followed,
})
else:
nowpage = int(pagenum)-1
now_page_content = paginatorlist.page(nowpage)
return render(request, "network/profile.html", {
"formattedlist": now_page_content, "currentnumber": nowpage, "use": use, "currentuser": currentuser, "follower_count": follower_count, "following_count": following_count, "followed": followed,
})
else:
if currentpage.has_next() == False:
return render(request, "network/profile.html", {
"formattedlist": currentpage, "currentnumber": pagenum, "message":'No next page', "use": use, "currentuser": currentuser, "follower_count": follower_count, "following_count": following_count, "list": formattedlist, "followed": followed,
})
else:
nowpage = int(pagenum)+1
now_page_content = paginatorlist.page(nowpage)
return render(request, "network/profile.html", {
"formattedlist": now_page_content, "currentnumber": nowpage, "use": use, "currentuser": currentuser, "follower_count": follower_count, "following_count": following_count, "followed": followed,
})
return render(request, "network/profile.html", {
"use": use, "currentuser": currentuser, "follower_count": follower_count, "following_count": following_count, "followed": followed, "formattedlist": now_page_content, "currentnumber": nowpage,
})
network/profile.html
{% extends "network/layout.html" %}
{% block body %}
<script src="http://127.0.0.1:8000/static/network/network.js"></script>
<div>
<h2 class="profiletext">{{use}}'s profile page</h2>
{{use}}
{% if message %}
<h6 style="color: red; margin-left: 10px">{{message}}</h6>
{% endif %}
<h5 class="profiletext">Follows: {{follower_count}} // Following: {{following_count}}</h5>
{% if use != currentuser %}
<form method="POST" class="profiletext" action="{% url 'profile' use %}">
{% csrf_token %}
{% if followed == False %}
<input type="submit" value="Follow" name="button">
{% else %}
<input type="submit" value="Unfollow" name="button">
{% endif %}
</form>
{% endif %}
</div>
{% for post in formattedlist %}
<div class="post">
<h5>{{post.use}}</h5>
<h6 style="font-weight: 60" class="edit"><a>Edit</a></h6>
<h4 class="content" style="font-size: 16px;">{{post.content}}</h4>
<h6 style="color: #d3d3d3; font-weight: 50">{{post.timestamp}}</h6>
<h1 class="hidden">{{post.id}}</h1>
{% if user.is_authenticated %}
<img src="https://cdn.shopify.com/s/files/1/0649/0603/products/bigo-0002-GH-8-bit-heart_grande.jpeg?v=1410449344">
<h2 class="likes">TODO</h2>
{% endif %}
</div>
{% endfor %}
<div>
<form class="pagination" method="POST" action="{% url 'profile' use %}">
{% csrf_token %}
<input type="submit" value="Previous" class="page-link" name="nav-button">
<input type="submit" value="Next" class="page-link" name="nav-button" >
<input type="text" value={{currentnumber}} class="pagenumber" name="pg">
</form>
</div>
{% endblock %}
I assume you have not changed user foreignkey from Post model. So, I guess your error is from this line:
<h5>{{post.use}}</h5>
So, it should be like:
<h5>{{ post.user }}</h5>
I have created a formset for users to add and remove forms as necessary using Django's empty_form and jQuery. However, when the form is submitted I am being thrown a validation error. I have initialized the ManagementForm, so I am not sure as to what the issue is. Any help would be greatly appreciated.
views.py
def presales(request):
PresalesFormSet = formset_factory(PresalesForm, extra=1, can_delete=True)
if request.method == 'POST':
presales_formset = PresalesFormSet(request.POST)
if presales_formset.is_valid():
selected_opportunity = request.POST.get('selected_opportunity')
for presales_form in presales_formset:
task_description = request.POST.get('task_description')
hours = request.POST.get('hours')
obj = Presales()
obj.opportunity = selected_opportunity
obj.taskDescription = task_description
obj.hours = hours
obj.save()
else:
presales_form = PresalesForm()
presales_formset = PresalesFormSet()
context = {'presales_formset': presales_formset, 'presales_form': presales_form, 'my_opportunities': my_opportunities}
return render(request, 'website/presales.html', context)
template.html
{{ presales_formset.management_form }}
<form action="{% url 'presales' %}" class="presales_formset" data-total-url="{% url 'presales_total' %}" id="presalesForm"
method="post" name="presalesForm">
<div class="field">
<label class="label is-large">High Level Task List</label>
</div>
{% csrf_token %}
{% for presales_form in presales_formset.forms %}
{{ presales_form.field_errors }}
{{ presales_form.errors }}
</form>
{% endfor %}
<div id="empty_form" style="display: none;">
{{ presales_formset.empty_form }}
<form action="{% url 'presales' %}" class="presales_formset" data-total-url="{% url 'presales_total' %}" id="emptyPresalesForm"
method="post" name="presalesForm">
{% csrf_token %}
</form>
</div>
forms.py
# special field names
TOTAL_FORM_COUNT = 'TOTAL_FORMS'
INITIAL_FORM_COUNT = 'INITIAL_FORMS'
MIN_NUM_FORM_COUNT = 'MIN_NUM_FORMS'
MAX_NUM_FORM_COUNT = 'MAX_NUM_FORMS'
ORDERING_FIELD_NAME = 'ORDER'
DELETION_FIELD_NAME = 'DELETE'
# default minimum number of forms in a formset
DEFAULT_MIN_NUM = 0
# default maximum number of forms in a formset, to prevent memory exhaustion
DEFAULT_MAX_NUM = 1000
class PresalesForm(forms.Form):
class Meta:
model = Presales
fields = ('selected_opportunity', 'task_description', 'hours', 'selected_engineer_level', 'total_price')
You need some additional data: form-TOTAL_FORMS, form-INITIAL_FORMS and form-MAX_NUM_FORMS. This data is required for the ManagementForm. Seems like you didn’t provide this management data. It should look like this:
data = {
'form-TOTAL_FORMS': '1',
'form-INITIAL_FORMS': '0',
'form-MAX_NUM_FORMS': '',
'form-0-title': '',
'form-0-pub_date': '',
}
That management_form should be inside your formset, like:
<form action="{% url 'presales' %}" class="presales_formset" data-total-url="{% url 'presales_total' %}" id="presalesForm"
method="post" name="presalesForm">
{{ presales_formset.management_form }}
<div class="field">
<label class="label is-large">High Level Task List</label>
</div>
{% csrf_token %}
{% for presales_form in presales_formset.forms %}
{{ presales_form.field_errors }}
{{ presales_form.errors }}
</form>
NoReverseMatch at /project/users/1/stories/1/
Reverse for 'user' with arguments '('',)' not found. 1 pattern(s) tried: ['project/users/(?P[0-9]+)/$']
Does anyone have any idea why I face this error when I press "python manage.py runserver"? It used to work just fine and now it just doesn't. I've seen that the problem might be with user_id or user.id, but I can't really see it! Here is my code:
project/views.py
def story(request, user_id, story_id):
if story_id is not None:
story = get_object_or_404(Story, pk=story_id)
else:
story = Story()
story.user_id = user_id
if request.method == 'POST':
story.title = request.POST['title']
story.story = request.POST['story']
story.date = timezone.now()
story.save()
return HttpResponseRedirect(reverse('project:story', args=(user_id,)))
else:
context = {
'user_id': user_id,
'story_id': story_id,
'title': story.title,
'story': story.story,
'likes': story.likes,
'comments': story.comments
}
return render(request, 'project/story.html', context)
project/urls.py
urlpatterns = [
path('', views.index, name='index'),
path('register/<int:user_id>/', views.register, name='register'),
path('login/<int:user_id>/', views.login, name='login'),
path('users/<int:user_id>/', views.user, name='user'),
path('users/<int:user_id>/stories/<int:story_id>/', views.story, name='story'),
]
project/templates/project/story.html
{% extends "project/base.html" %}
{% block content %}
{% if story_id %}
<div class="post-preview">
<h2 class="post-title"> {{ story.title }}</h2>
<p class="post-subtitle">
{{ story.story }}
</p>
<p class="post-meta">Posted by
{{ story.author.username }}
on {{ story.date }}
<i class="fas fa-thumbs-up"> {{ story.likes }}</i>
<i class="fas fa-comment"> {{ story.comments }}</i>
</p>
</div>
<div class="post-preview">
<h2> Comments </h2>
{% for com in latest_comments %}
<div class="post-preview">
<p class="post-subtitle"> {{ comment.com }}</p>
</div>
{% endfor %}
</div>
<div class="post-preview">
<form action="{% url 'project:story' user.id story.id %}" method="post">
{% csrf_token %}
<div class="form-group">
<label for="text">Comment</label>
<textarea id="text" name="text"
class="form-control" placeholder="Comment" rows="4">{{ comment.com }}
</textarea>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
{% else %}
{% if request.story.author.id == user.id %}
<form action="{% url 'project:story' user.id story.id %}" method="post">
{% csrf_token %}
<div class="form-group">
<label for="title">Title</label>
<input type="text" id="title" name="title"
class="form-control" placeholder="Title" value="{{ story.title }}"/>
</div>
<div class="form-group">
<label for="text">Story</label>
<textarea id="text" name="text"
class="form-control" placeholder="Story" rows="10">{{ story.story }}
</textarea>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
{% endif %}
{% endif %}
{% endblock %}
In your context we see:
context = {
'user_id': user_id,
'story_id': story_id,
'title': story.title,
'story': story.story,
'likes': story.likes,
'comments': story.comments
}
so the story variable does not contain a Story object, it contains its story attribute (probably, based on the rest of the view, a string).
Now in your template you write:
{% url 'project:user' story.author.id %}
but since story is a string, it has no .author attribute, so this will get evaluated to the string_if_invalid which is, unless you specified otherwise, the empty string ''.
You thus need to pass the story itself in your context to:
context = {
'user_id': user_id,
'story_id': story_id,
'title': story.title,
'story': story,
'likes': story.likes,
'comments': story.comments
}