NoReverseMatch at /reviews/ Reverse for 'reviews_detail' with arguments - python

Have serious issues with the following.
have a reviews app in my project where people can read, leave, edit and delete views.
Was all working fine in gitpod on the local side but then when i pushed to Heroku i started getting errors. On Heroku I was gettings a null constraint error and on the local side I was getting "null value in column" error. I cleared my database, deleted users and created a new superuser after updating the models to use uuid instead. Now i'm getting a noreverse error on the local side (god only knows what's going to happen when i push it to Heroku but lets deal with one thing at a time).
Anyways I'll attach all relevant code below.
Have a project due tomorrow so any help would be massively appreciated.
reviews.html
{% extends "base.html" %}
{% load static %}
{% block content %}
<div class="container-fluid text-white">
<div class="row mt-5">
{% for review in object_list %}
<div class="col col-md-3 reviews">
<h1 class="pt-3">Title: {{ review.title }}</h1>
{% if request.user.is_authenticated %}
{% if user.id == review.user.id %}
Edit
Delete<br>
{% endif %}
{% endif %}
{{ review.review|slice:":50" }}<br>
{{ review.user }}<br>
{{ review.rate }} Stars<br>
{{ review.created_at }}
</div>
{% endfor %}
</div>
<div class="row">
<div class="col">
<a href="{% url 'add_review' %}">
<h1 class="headings">Leave a Review</h1>
</a>
</div>
</div>
</div>
{% endblock %}
models.py
import uuid
from django.db import models
from django.contrib.auth.models import User
RATINGS = (
(1, '1'),
(2, '2'),
(3, '3'),
(4, '4'),
(5, '5'),
)
class UserReviews(models.Model):
""" model for user reviews used to create and view reviews """
title = models.CharField(max_length=50, blank=True)
review = models.TextField(max_length=1000)
user = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
rate = models.IntegerField(choices=RATINGS, blank=True)
created_at = models.DateTimeField(auto_now_add=True)
urls.py
from django.urls import path
from .views import ReviewListView, ReviewDetailView, ReviewFormView, UpdateReviewView, DeleteReviewView
urlpatterns = [
path('add_review/', ReviewFormView.as_view(), name='add_review'),
path('', ReviewListView.as_view(), name='reviews'),
path('reviews/<int:pk>', ReviewDetailView.as_view(),
name='reviews_detail'),
path('review/update/<int:pk>', UpdateReviewView.as_view(), name='update_review'),
path('review/<int:pk>/delete/', DeleteReviewView.as_view(), name='delete_review'),
]
views.py
""" imports from django, models.py and forms.py """
from django.views.generic import ListView, DetailView, CreateView, UpdateView, DeleteView
from django.urls import reverse_lazy
from .models import UserReviews
from .forms import UserReviewForm
class ReviewListView(ListView):
""" view for generating the review list """
model = UserReviews
template_name = "reviews/reviews.html"
ordering = ['-created_at']
class ReviewDetailView(DetailView):
""" view for generation Review Details """
model = UserReviews
template_name = "reviews/reviews_detail.html"
class ReviewFormView(CreateView):
""" view for review form """
model = UserReviews
template_name = "reviews/add_review.html"
form_class = UserReviewForm
success_url = reverse_lazy('reviews')
class UpdateReviewView(UpdateView):
""" view for updating review form """
model = UserReviews
template_name = "reviews/update_review.html"
form_class = UserReviewForm
class DeleteReviewView(DeleteView):
""" view for deleting review form """
model = UserReviews
template_name = "reviews/delete_review.html"
success_url = reverse_lazy('reviews')
forms.py
from django import forms
from .models import UserReviews
class UserReviewForm(forms.ModelForm):
""" meta data to generate contact us form """
class Meta:
""" form model, fields and widgets used"""
model = UserReviews
fields = [
'title', 'review', 'rate'
]
def form_valid(self, form):
# if form is valid return to discussion
form.instance.user = self.request.user
return super().form_valid(form)

Related

Slug URL turns into a number when navigating to the next link in django

I tried searching for this problem here but I didn't find anything, I hope someone can help answering or sending a link to a solution on stackoverflow...
I have been creating a blog, and when I click on the post title, it goes to 'post_details.html' and in the URL shows a slug with the post title. Like here:
examplename.com/blog/brooklyn-nets-at-miami-heat-preview/
But when I click to write a comment on the post it takes me to a form page, but the slug title disappear, it just shows the post number. Like this:
examplename.com/blog/3/add-comment
Can someone explain why is this happening? I want to know how to solve this and understand from where it comes this number that shows up.
Post_detail.html
{% block content %}
<h2 class="title">
<a class="post-title" href="{{ post.get_absolute_url }}">
{{ post.title }}
</a>
</h2>
<p class="date">
Publicado em {{ post.created }} por {{ post.author }}
</p>
{{ post.body|linebreaks }}
<hr>
<h3>Comments</h3>
{% if not post.comments.all %}
Nobody commented yet...Add a comment
{% else %}
Add a comment
{% for comment in post.comments.all %}
{{ comment.name }}
{{ comment.date }}
<br>
{{ comment.body }}
{% endfor %}
{% endif %}
<a class="swen" href="{% url 'blog:list' %}">More Articles</a>
{% endblock %}
urls.py
from unicodedata import name
from django.urls import path
from . import views
app_name = 'blog'
urlpatterns = [
path("", views.PostListView.as_view(), name="list"),
path("<slug:slug>/", views.PostDetailView.as_view(), name="detail"),
path("<slug:slug>/add-comment", views.CommentView.as_view(), name="commentview")
]
models.py
from django.contrib.auth.models import User
from django.db import models
from django.urls import reverse
class Post(models.Model):
title = models.CharField(max_length=255)
slug = models.SlugField(max_length=255, unique=True)
author = models.ForeignKey(User, on_delete=models.CASCADE)
body = models.TextField()
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse ('blog:detail', kwargs={"slug":self.slug})
class Meta:
ordering = ("-created",)
class Comment(models.Model):
post = models.ForeignKey(Post, related_name="comments", on_delete=models.CASCADE)
name = models.CharField(max_length=255)
body = models.TextField()
date = models.DateField(auto_now_add=True)
slug = Post.slug
def __str__(self):
return reverse (self.post.title, self.name, self.post.slug)
views.py
from xml.etree.ElementTree import Comment
from django.views.generic import DetailView, ListView, CreateView
from .models import Post, Comment
class PostListView(ListView):
model = Post
class PostDetailView(DetailView):
model = Post
class CommentView(CreateView):
model = Comment
template_name = 'add_comment.html'
fields = '__all__'
you're passing pk which is a type integer as parameter instead of a slug at path name commentview. May be you should check on that.

Django simple forum project not displaying modles on page

I have been working on a simple forums application for a few weeks now. The main goal of the project is to have sooner written a post and then for the post to be displayed. The project does not utilize user models. For some reason when the user completes the form for their post their post is not displayed. I was wondering if anyone knew why this is happening or if any of y'all have any tips.
views.py
from django.shortcuts import render
from django.urls import reverse_lazy
from django.views import generic
from . import forms
# Create your views here.
class ForumForm(generic.CreateView):
template_name = 'forums_simple/forum.html'
form_class = forms.ForumForm
success_url = '/'
def form_vaild(self, form):
self.object = form.save(commit=False)
self.object.save()
return super().form_vaild(form)
urls.py
from django.contrib import admin
from django.urls import path, include
from . import views
app_name = 'forums'
urlpatterns = [
path('', views.ForumForm.as_view(), name='forum')
]
models.py
from django.db import models
# Create your models here.
class Post(models.Model):
message = models.TextField(blank=True, null=False)
created_at = models.DateTimeField(auto_now=True)
forms.py
from django import forms
from . import models
class ForumForm(forms.ModelForm):
class Meta:
model = models.Post
fields = ('message',)
forum.html
{% extends "base.html" %}
{% load crispy_forms_tags %}
{% block content %}
<div class="container">
{% for message in object_list %}
{{ post.message }}
{% endfor %}
</div>
<div class="container">
<form class="forum_class" action="index.html" method="post">
{% csrf_token %}
{% crispy form %}
<button type="submit" name="big-button"></button>
</form>
</div>
{% endblock %}
You need to add object_list to your context in the view so:
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
# don't forget to import Post
context['object_list'] = Post.objects.all()
return context

I am using CreateView in django but getting error- The view blog.views.PostCreateView didn't return an HttpResponse object. It returned None instead

I am having a post model with a user having OneToMany Relationship with inbuilt user model for authentication
my urls.py
from django.contrib import admin
from django.urls import path, include
# from views import PostView
from . import views
urlpatterns = [
path('', views.PostView.as_view(), name='blogHome'),
path('post/<int:pk>/', views.PostDetailView.as_view(), name='post-detail'),
path('post/new/', views.PostCreateView.as_view(), name='post-create'),
path('about/', views.about, name='about')
]
my views.py
from django.shortcuts import render
from django.http import HttpResponse
from .models import Post
from django.views.generic import (
ListView,
DetailView,
CreateView
)
# Create your views here.
def home(request):
context = {
'posts': Post.objects.all()
}
return render(request, 'blog/home.html', context)
def about(request):
return render(request, 'blog/about.html')
class PostView(ListView):
model = Post
template_name = 'blog/home.html'
context_object_name = 'posts'
ordering = ['-date_published']
class PostDetailView(DetailView):
model = Post
class PostCreateView(CreateView):
model = Post
fields = ['title', 'body']
#to add author before validation
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
Post Model
from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User
# Create your models here.
class Post(models.Model):
author = models.ForeignKey(User, on_delete=models.CASCADE)
title = models.CharField(max_length=100)
body = models.TextField()
date_published = models.DateTimeField(default=timezone.now)
def __str__(self):
return self.title
I am using post_form.html as the template name
post_form.html
{% extends 'blog/layout.html' %}
{% load crispy_forms_tags %}
{% block body %}
<div class="content-section p-20">
<form method="POST">
{% csrf_token %}
<fieldset class="form-group p-30">
<legend class="border-bottom mb-4">Create new post</legend>
{{ form|crispy }}
</fieldset>
<div class="form-group">
<button class="btn btn-outline-info" type="submit">Create</button>
</div>
</form>
</div>
{% endblock %}
I am a beginner in Django , please tell if anything more is needed to solve the problem. Also why this type of error is coming only with Createview and not with other views
Apparently the return of super().form_valid(form) is None and not a valid response. I don't know much of this design pattern in Django but seeing your other methods seems like this view is decorated by some method which returns a valid response. So you should not return something in your implementation. So, drop the return and test again.

Django Form: django-autocomplete-light is showing empty dropdown

I am building a web app in Django trying to use django-autocomplete-light(v.3.8.2) to create an auto-complete field. I have form that allows users to create a Trade record. I'm trying to add an auto-complete field for Trade.owned_game (a lookup field). I am just getting an empty dropdown field for the auto-complete field (screenshot attached at bottom of this post) Below is my code:
models.py:
from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User
from django.urls import reverse
class Game(models.Model):
name = models.TextField() # Unrestricted text
platform = models.CharField(max_length=100) # character field
created_date = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return self.name # return game name when game.objects.all() is called
class Trade(models.Model):
name = models.TextField() # Unrestricted text
created_date = models.DateTimeField(default=timezone.now)
is_trade_proposed = models.BooleanField(default=False)
user_who_posted = models.ForeignKey(User, on_delete=models.CASCADE)
owned_game = models.ForeignKey(Game, on_delete=models.CASCADE, related_name='owned_game', db_column='owned_game')
def __str__(self):
return self.name # return game name when game.objects.all() is called
urls.py:
from django.urls import path
from django.conf.urls import url
from .views import (
PostListView,
TradeListView,
PostDetailView,
TradeCreateView,
GameAutoComplete,
PostUpdateView,
PostDeleteView,
UserPostListView
)
from . import views
urlpatterns = [
path('', views.home, name='blog-home'),
path('post/new/', views.trade_new, name='trade-create'),
url(
r'^game-autocomplete/$',
GameAutoComplete.as_view(),
name='game-autocomplete')
,
]
views.py:
from django.shortcuts import render, get_object_or_404
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from django.contrib.auth.models import User
from django.views.generic import (
ListView,
DetailView,
CreateView,
UpdateView,
DeleteView
)
from .models import Trade, Game
def trade_new(request):
form = TradeCreateForm()
return render(request, 'blog/trade_form.html', {'form': form, 'title': 'asdf'})
class TradeCreateForm(forms.ModelForm):
game = forms.ModelChoiceField(
queryset=Game.objects.all(),
to_field_name = 'name',
widget=autocomplete.ModelSelect2(url='game-autocomplete')
)
class Meta:
model = Trade
fields = ['owned_game', 'desired_game']
class TradeCreateView(LoginRequiredMixin, CreateView):
model = Trade
fields = ["owned_game"]
class GameAutoComplete(autocomplete.Select2QuerySetView):
def get_queryset(self):
if not self.request.user.is_authenticated:
return Game.objects.none()
qs = Game.objects.all()
if self.q:
qs = qs.filter(name__istartswith=self.q)
return qs
trade_form.html:
{% extends "blog/base.html" %}
{% load crispy_forms_tags %}
{% block content %}
<div class="content-section">
<form method="POST">
{% csrf_token %}
<fieldset class="form-group">
<legend class="border-bottom mb-4">Propose New Trade</legend>
{{ form|crispy }}
{{ form.media }}
</fieldset>
<div class="form-group">
<button class="btn btn-outline-info" type="submit">Submit</button>
</div>
</form>
</div>
{% endblock content %}
Screenshot:
enter image description here
I have tried the solutions from these similar StackOverflow questions but they're not working:
Django-autocomplete-light showing empty dropdown instead of autocomplete widget
django-autocomplete-light displays empty dropdown in the form
I should have checked the javascript console earlier! The problem was one of the <link ...> scripts for jQuery was invalid. Once i fixed that, the auto-complete field worked

Django generic UpdateView returns 404 error: "No user found matching the query" when using pk

I am creating a Django web app and want to use the generic UpdateView by passing in a user's primary key. It works for the DetailView, but not the UpdateView.
I've tried specifying the template_name, changing the order of paths in my urls.py file. I haven't tried using a slug yet, but I know I should be able to use a pk.
I am using the built-in User model from django.contrib.auth below for my profile.
views.py:
class Profile(generic.TemplateView):
template_name = 'accounts/profile.html'
class ProfileUpdate(generic.UpdateView):
model = User
fields = ['first_name']
template_name = 'accounts/profile_update_form.html'
models.py
from django.db import models
from django.contrib import auth
# Create your models here.
class User(auth.models.User,auth.models.PermissionsMixin):
readonly_fields = ('id',)
def __str__(self):
return self.username
class UserProfile(models.Model):
user = models.OneToOneField(auth.models.User,on_delete=models.CASCADE)
join_date = models.DateTimeField(auto_now=True)
profile_pic = models.ImageField(upload_to='profile_pics',default='media/block-m.png')
skills = models.TextField()
major = models.CharField(max_length=128)
grad_year = models.CharField(max_length=4)
clubs = models.TextField() #make FK to Clubs
opt_in = models.BooleanField(default=True)
def __str__(self):
return self.user.username
My urls.py is what frustrates me the most. The address http://127.0.0.1:8000/accounts/profile/5/ works fine, but http://127.0.0.1:8000/accounts/profile/5/edit/ returns a 404 error "No user found matching the query". So I know that the pk=5 exists, but doesn't work for my url ending in /edit/.
urls.py:
from django.urls import path,include
from django.contrib.auth import views as auth_views
from . import views
app_name = 'accounts'
urlpatterns = [
path('login/',auth_views.LoginView.as_view(template_name='accounts/login.html'),name='login'),
path('logout',auth_views.LogoutView.as_view(),name='logout'),
path('signup/',views.SignUp,name='signup'),
path('profile/<int:pk>/',views.Profile.as_view(),name='profile'),
path('profile/<int:pk>/edit/',views.ProfileUpdate.as_view(),name='profile_update'),
]
profile_update_form.html:
{% extends 'base.html' %}
{% load bootstrap4 %}
{% block content %}
<div class="container">
<h2>Sign Up</h2>
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
{% bootstrap_form form layout='inline' %}
<input type="submit" class="btn btn-primary" value="Sign Up">
</form>
</div>
{% endblock %}
That's because user.pk is not the same as primary key for the same users userprofile, if you check their respectable tables in database you will see the difference, yes it is confusing at first simplest solution I did is using signals:
def profile_creation_signal(sender, instance, created, **kwargs) :
if created:
UserProfile.objects.create(pk=instance.id, user=instance)
post_save.connect(profile_creation_signal, sender=User)
It should work!
path('<username>/', ProfileView.as_view(), name="public_profile"),
class ProfileView(DetailView):
model = User
template_name = "pages/public_profile.html"
context_object_name = "profile"
slug_field = "username"
slug_url_kwarg = "username"
You can replace -username- with unique fields

Categories

Resources