so I encountered a NoReverseMatch exception in my Django app. It shows me this type of exception:
Reverse for 'user-profile' with arguments '('',)' not found. 1 pattern(s) tried: ['profile/(?P[^/]+)/$']
feed_component.html code:
<div>
{% for room in rooms %}
<div>
{% if request.user == room.host %}
Edit
Delete
{% endif %}
#{{room.host.id}}
<h5>{{room.id}} --> {{room.name}}</h5>
<small>{{room.topic.name}}</small>
<hr>
</div>
{% endfor %}
So my biggest surprise is that in:
#{{room.host.id}}
#{{room.host.id}} render excatly what i want on page - id. But this part:
{% url 'user-profile' room.host.id %}"
Throws exception...
and when i change it to:
#{{room.host.id}}
There is no exceptions, it works ok but i really need that id...
urls.py
path('profile/<str:pk>/', views.userProfile, name="user-profile"),
views.py
def userProfile(request, pk):
user = User.objects.get(id=pk)
rooms = user.room_set.all()
room_messages = user.message_set.all()
topics = Topic.objects.all()
context = {'user': user, 'rooms': rooms, 'room_messages': room_messages, 'topics': topics}
return render(request, 'baseapplication/profile.html', context)
models.py
class Room(models.Model):
host = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
topic = models.ForeignKey(Topic, on_delete=models.SET_NULL, null=True)
name = models.CharField(max_length=200)
description = models.TextField(null=True, blank=True)
participants = models.ManyToManyField(User, related_name='participants', blank=True)
updated = models.DateTimeField(auto_now=True)
created = models.DateTimeField(auto_now_add=True)
Any ideas ?
Related
I have 3 models and I need to display the area and need items only if there is at least 1 product connected. If there are no products in particular Area and Need models then it should not appear in my HTML file.
I have checked the documentation and several answers related to this topic but I cannot implement it in my script.
I also tried to create my custom filter so I can apply it directly in my template but nothing worked.
My problem is that I am getting the list of all items from Need model and I don't know how to exclude empty items from HTML page.
I will appreciate any help.
models.py
class Area(models.Model):
title = models.CharField(max_length=75, blank=False)
body = models.CharField(max_length=150, default='-', blank=False)
publish = models.DateTimeField('publish', default=timezone.now)
class Need(models.Model):
title = models.CharField(max_length=75, blank=False, null=False, help_text='max 75 characters')
body = models.CharField(max_length=150, default='-', blank=False)
publish = models.DateTimeField(default=timezone.now)
need_area = models.ForeignKey(Area, on_delete=models.CASCADE, related_name='need_area')
class ProductCategory(models.Model):
title = models.CharField(max_length=400, blank=False, null=False, help_text='max 400 characters')
body = models.TextField(default='-')
publish = models.DateTimeField('publish', default=timezone.now)
category_area = models.ForeignKey(Area, on_delete=models.CASCADE, related_name='category_area', null=True)
category_need = models.ForeignKey(Need, on_delete=models.CASCADE, related_name='category_need', null=True)
class Product(models.Model):
id = models.AutoField(primary_key=True)
title = models.CharField(max_length=400, blank=False)
category = models.ForeignKey(ProductCategory, on_delete = models.CASCADE, blank=True, related_name='products')
status = models.IntegerField(choices=STATUS, default=0)
def get_absolute_url(self):
return reverse("product", kwargs={'slug': self.slug})
views.py
class Search(ListView):
template_name = 'search.html'
model = Product
queryset = Product.objects.filter(status=1)
def get_context_data(self, **kwargs):
context = super(Search, self).get_context_data(**kwargs)
filter_need = Area.objects.filter(Exists(Need.objects.filter(need_area=OuterRef('pk'))))
areas = Area.objects.prefetch_related(Prefetch('need_area', queryset=filter_need, to_attr='need_area__category_need__product')).filter(need_area__category_need__product__status=1).distinct()
context['areas'] = areas
return context
search.html
{% if areas %}
{% for area in areas %}
<div class="border mb-4 pb-4 px-2">
<h2 class="fw-bold my-2">{{area.title}}</h2>
{% for need in area.need_area.all %}
<h4 class="text-muted mt-4">{{need.title}}:</h4>
{% for product_category in need.category_need.all %}
{% for product in product_category.product.all %}
<span class="rounded-pill bg-hubble text-dark f-12 p-2">{{product.title}}</span>
{% endfor %}
{% endfor %}
{% endfor %}
</div>
{% endfor %}
{% endif %}
I am working on my project I faced a problem with "COMMENT":
I add a comment as a section when the user clicks "view" button to see the post from the home page.
Django error :
NoReverseMatch at /Post/8
Reverse for 'comments' with arguments '('',)' not found. 1 pattern(s) tried: ['Post/(?P[0-9]+)$']
views.py file
def viewList(request, id):
item = Post.objects.get(id=id)
context = {
'item': item,
'comment_form': comment(),
'comments': item.get_comments.all(),
}
return render(request, 'auctions/item.html', context)
#login_required
def comments(request, id):
listing = Post.objects.get(id=id)
form = comment(request.PSOT)
newComment = form.save(commit=False)
newComment.user = request.user
newComment.listing = listing
newComment.save()
return HttpResponseRedirect(reverse("listing", {'id': id}))
models.py file
class Post(models.Model):
# data fields
title = models.CharField(max_length=64)
textarea = models.TextField()
# bid
price = models.FloatField(default=0)
currentBid = models.FloatField(blank=True, null=True)
imageurl = models.CharField(max_length=255, null=True, blank=True)
category = models.ForeignKey(
Category, on_delete=models.CASCADE, default="No Category Yet!", null=True, blank=True)
creator = models.ForeignKey(User, on_delete=models.PROTECT)
watchers = models.ManyToManyField(
User, blank=True, related_name='watched_list')
date = models.DateTimeField(auto_now_add=True)
# for activated the Category
activate = models.BooleanField(default=True)
def __str__(self):
return f"{self.title} | {self.textarea} | {self.date.strftime('%B %d %Y')}"
class Comment(models.Model):
body = models.CharField(max_length=100)
createdDate = models.DateTimeField(default=timezone.now)
# link to the post model
auction = models.ForeignKey(
Post, on_delete=models.CASCADE, related_name="get_comments")
user = models.ForeignKey(User, on_delete=models.CASCADE)
status = models.BooleanField(default=True)
def __str__(self):
return self.createdDate.strftime('%B %d %Y')
HTML file
<!-- Comments -->
<div class="comments">
<p>Add a comment:</p>
<div class="row">
<div class="col-6">
<form action="{% url 'comments' listing.id %}" method="post">
{% csrf_token %}
<div class="input-group">
{{ comment_form }}
</div>
<input type="submit" value="save" class="btn btn-outline-dark btn-sm m-1"/>
</form>
</div>
{% for comment in comments %}
<div class="col-4">
Comments:
<h4>Name: {{comment.user}}</h4>
<h4>Content: {{comment.body}}</h4>
<h4>Date: {{comment.createdDate}}</h4>
</div>
{% endfor %}
</div>
</div>
url.py
from django.urls import path
from . import views
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("category/", views.category, name="category"),
path("Post", views.createList, name="createList"),
#comment url
path("Post/<str:id>", views.viewList, name="viewList"),
path("Post/<int:id>", views.comments, name="comments"),
]
You passed the Post object as item to the template, hence you should resolve the URL with:
<!-- use item not listing ↓ -->
<form action="{% url 'comments' item.id %}" method="post">
…
</form>
Your view to create comments also has some mistakes: you should use request.POST, not request.PSOT:
from django.shortcuts import redirect
#login_required
def comments(request, id):
if request.method == 'POST'
form = comment(request.POST, request.FILES)
if form.is_valid():
form.instance.user = request.user
form.instance.auction_id = id
form.save()
return redirect('viewList', id=id)
Furthermore your comment form should inherit from ModelForm and not Form:
class comment(forms.ModelForm):
class Meta:
model = Comment
fields = ('content',)
widgets = {
'content': forms.Textarea(attrs={"class": "form-control"})
}
finally your urls.py has two (fully) overlapping patterns, you should use a different URL to add the given comment:
urlpatterns = [
# …
#comment url
path('Post/<int:id>', views.viewList, name='viewList'),
path('Post/<int:id>/add', views.comments, name='comments'),
]
Note: Usually a Form or a ModelForm ends with a …Form suffix,
to avoid collisions with the name of the model, and to make it clear that we are
working with a form. Therefore it might be better to use CommentForm instead of
comment.
I'm new to Django. i'm trying to display all the comments for a listing in an auction site
Help me find a way to display all the comments for a listing.
Mosdels.py
class Listing(models.Model):
title = models.CharField(max_length=64, default="")
starting_bid = models.CharField(max_length=64, default="$")
description = models.TextField(default="")
image_url = models.CharField(max_length=200, default="")
date = models.DateTimeField(default=timezone.now)
category = models.ForeignKey(Category, on_delete=models.CASCADE, default="")
def __str__(self):
return self.title
class Comment(models.Model):
comment = models.TextField(default="")
listing = models.ForeignKey(Listing, on_delete=models.CASCADE, related_name="comments", default="")
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="comments", default="")
def __str__(self):
return f"{self.user} - {self.listing}"
views.py
def listing(request, listing_id):
listing = Listing.objects.get(pk=listing_id)
comments = listing.comments.all()
return render(request, "auctions/listing.html", {
"listing":listing,
"comments":comments
})
_If you are trying to display in a template you can use something like following:
{% for listing_item in listing %}
<div>{{listing_item.title}}
{% for comment in listing_item.comment_set.all %}
<div>{{comment}}</div>
{% endfor %}
</div>
{% endfor %}
EDIT: If only sending the one listing from your view:
{{listing.title}}
{% for comment in listing.comment_set.all %}
<div>{{comment}}</div>
{% endfor %}
EDIT2: Noticed you have a related name there.
{{listing.title}}
{% for comment in listing.comments.all %}
<div>{{comment}}</div>
{% endfor %}
How do I make the page list all posts that that share the same category id? I have the category titles as a separate "foreign key" model. My goal is to be able to type in my URL so that I have the category id at the end and it shows me all the posts that have the specific category id.
"""models.py"""
class Category(models.Model):
name = models.CharField(max_length=200)
slug = models.SlugField()
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('post-category', kwargs={'pk': self.pk})
class HelpPage(models.Model):
title = models.CharField(max_length=100)
content = models.TextField(default="test")
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
product = models.CharField(max_length=100)
category = models.ForeignKey('Category', null=True, blank=True, on_delete=models.CASCADE)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('post-detail', kwargs={'pk': self.pk})
"""views.py"""
class CategoryDetailView(DetailView):
model = Category
context_object_name = 'category'
template_name = 'blog/categories.html'
"""urls.py"""
from .views import (
CategoryDetailView,)
urlpatterns = [
path('category/<int:pk>', CategoryDetailView.as_view(), name='post-category'),]
"""categories.html"""
{% extends "blog/base.html" %}
{% block content %}
Category name: {{ category.name }}
{% for post in category.post_set.all %}
post: {{ post.title }}
{% endfor %}
{% endblock content %}
In your DetailView you'll need to capture the category ID passed through urls.py. Here is some info on how to do that:
https://www.agiliq.com/blog/2019/01/django-when-and-how-use-detailview/
Once you have that you can use it to run a query like this to filter for specific posts:
HelpPage.objects.filter(category__id=id)
I'm developing a website based on Django==1.5.7
I need to paginate the ListView of a table in my application.
This is the code i'm using
On models.py:
class UsuarioFidetel(models.Model):
"""
Modelo de usuario fidetel
"""
usuario = models.CharField(max_length=30)
id_usuario = models.IntegerField()
nombre = models.CharField(max_length=255, null=True)
apellido = models.CharField(max_length=255, null=True)
tipo_cedula = models.CharField(max_length=1, null=True)
cedula = models.CharField(max_length=9, null=True)
fecha_nacimiento = models.DateField(null=True, blank=True)
sexo = models.CharField(max_length=1, null=True)
correo = models.EmailField(max_length=254, null=True)
estado_civil = models.CharField(max_length=1, null=True)
def __unicode__(self):
return self.nombre
On views.py:
class UsarioList(ListView):
model = UsuarioFidetel
template_name = 'all_list.html'
On urls.py:
url(r'^usario/$', UsarioList.as_view(model=UsuarioFidetel, paginate_by=2)),
Note the paginate_by attribute of the url, this is working just fine, but when I go to the 2nd page, or whatever page, outside the 1st one, it throws this error:
Page not found (404)
Request Method: GET
Request URL: http://127.0.0.1:9001/usario?page=2
All is working fine, but I thought this will pass the page inside the block of my template, without major errors, can't figure out what's wrong here, maybe I need a regex on the url?
Any ideas?
Thanks in advance!
Nevermind, solved it on template, ie:
<span class="page-links">
{% if page_obj.has_previous %}
<
{% endif %}
<span class="page-current">
Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
</span>
{% if page_obj.has_next %}
>
{% endif %}
</span>
Now it works the way it should