Reverse not found with slug field - python

I am getting error while using get_absolute_url with slug field. Have tried few suggestions which are already exist in stack but didn't worked. Can anyone help me with this please.
Please refer this link for traceback.
models.py
Codes in models.
from django.urls import reverse
class Post(models.Model):
title = models.CharField(max_length=50)
user = models.ForeignKey(settings.AUTH_USER_MODEL, default=1, on_delete=models.CASCADE)
draft = models.BooleanField(default=False)
publish = models.DateTimeField(auto_now=False, auto_now_add=False)
slug = models.SlugField(unique=True)
image = models.ImageField(upload_to=upload_location,
null=True,
blank=True,
width_field="width_field",
height_field="hieght_field")
hieght_field = models.IntegerField(default=0)
width_field = models.IntegerField(default=0)
content = models.TextField()
updates = models.DateTimeField(auto_now=True, auto_now_add=False)
timestamp = models.DateTimeField(auto_now=False, auto_now_add=True)
def get_absolute_url(self):
return reverse('post:detail', kwargs={'slug':self.slug})
Views.py
codes in views.
def post_list(request):
queryset_list = Post.objects.active()
if request.user.is_staff or request.user.is_superuser:
queryset_list = Post.objects.all()
query = request.GET.get('q')
if query:
queryset_list = queryset.filter(
Q(title__icontains=query)
).distinct()
context = {
'object_list':queryset_list,
'posts': page,
"page_request_var": page_request_var,
}
return render(request, 'index.html', context)
urls.py
urls mapping.
urlpatterns = [
path('detail/<slug:slug>/', views.detail, name='detail'),
]
html page
code in index.html
{% for obj in object_list %}
<div class="container">
<p class="card-text">{{obj.content|linebreaks|truncatechars:120}}</p>
View
<!-- {{obj.title}} -->
</div>
{% endfor %}

Error was occurring because of commented line in index.html {{obj.title}} after removing this line page is getting loaded perfectly and one more thing 'pk' should be replaced by slug in detail view to work detail page. def detail(request,slug): #slug replaced pk

Related

{% for projects in profile.project_set.all %} is not displaying anything

I have been learning django through a video course and in the video course the guys has used
{% for projectss in profile.project_set.all %}
{{ projectss.title }}
{% endfor %}
To display List of projects
Here is my Model.py file of project model
class Project(models.Model):
owner = models.ForeignKey(Profile, null=True, blank=True, on_delete=models.SET_NULL)
title = models.CharField(max_length=200)
id = models.UUIDField(default = uuid.uuid4 , primary_key=True, unique=True,
editable=False)
And Here is my Model.py of Users model
class Profile(models.Model):
user = models.OneToOneField(User,on_delete=models.CASCADE)
id = models.UUIDField(default=uuid.uuid4, primary_key=True, editable=False, unique=True)
View.py file
def userProfile(request, pk):
obj = Profile.objects.get(id=pk)
context = {'user': obj}
return render(request, 'users/user_profile.html', context)
The guy in video is doing the same thing its working for him but not me.
Look at the context you are passing to the view:
context = {'user': obj}
Change 'user' to 'profile' and you should be good.
def userProfile(request, pk):
obj = Profile.objects.get(id=pk)
context = {'profile': obj}
return render(request, 'users/user_profile.html', context)

How to render view from differents applications in the same template?

I have two applications (blog and category). On the post list template I would like to get the category blog name and description.
I have tried to put the import category model in the blog view, but nothing show up. So I have made two views rendering the same template, but it does not work.
Blog models:
from django.db import models
from django.utils import timezone
from autoslug import AutoSlugField
from category.models import Category
class Post(models.Model):
author = models.ForeignKey('auth.User', on_delete=models.CASCADE)
category = models.ForeignKey(Category, on_delete=models.CASCADE,
default = '')
title = models.CharField(max_length=200)
...
class Meta:
verbose_name = "Post"
verbose_name_plural = "Posts"
ordering = ['created_date']
def publish(self):
self.published_date = timezone.now()
self.save()
def __str__(self):
return self.title
category models:
class Category(models.Model):
name = models.CharField(max_length=200)
slug = AutoSlugField(populate_from='name', default='')
parent = models.ForeignKey('self', blank=True, null=True, related_name='children', on_delete=models.CASCADE)
description = models.TextField(max_length=200)
class Meta:
unique_together = ('slug', 'parent',) # Enforcing that there can not be two
verbose_name_plural = "categories" # categories under a parent with same
# slug
def __str__(self): # __str__ method elaborated later in
full_path = [self.name] # post. use __unicode__ in place of
# __str__ if you are using python 2
k = self.parent
while k is not None:
full_path.append(k.name)
k = k.parent
return ' -> '.join(full_path[::-1])
Blog view:
def post_list(request):
posts = Post.objects.all()
cat_blog = Category.objects.get(pk=1)
context = {
'posts': posts,
'cat_blog': cat_blog
}
return render(request, 'blog/post_list.html', context)
Category view:
def cat_blog(request):
cat_blog = Category.objects.get(pk=1)
return render(request, 'blog/post_list.html', {'cat_blog': cat_blog})
post_list.html:
<div class="section-header text-center">
{% for category in cat_blog %}
<h1>{{ category.name }}</h1>
<p class="tag">{{ category.description }}</p>
{% endfor %}
</div>
<div class="row py-5">
{% for post in posts %}
// This part is fine
{% endfor%}
The post loop is fine. How can't I get the category name and description in my section header?
One URL gives one View gives one template.
You use the View to give context to the template to render.
def post_list(request):
posts = Post.objects.all()
cat_blog = Category.objects.get(pk=1)
context = {
'posts': posts,
'cat_blog': cat_blog
}
return render(request, 'blog/post_list.html', context)
Your url.py file should point to the post_list view.

Django One to Many relationship urls

I use to django for my web site. But ı have a question about blog/urls.py(my app name is blog )
I use to with one to many releationship in blog/models.py.
Category (1 => *) Subject (1 => *) Article.
class Category(models.Model):
name = models.CharField(max_length=200)
statement = models.TextField()
slug=models.SlugField()
page_name = models.ForeignKey('Page', on_delete=models.CASCADE)
def __str__(self):
return self.name
class Subject(models.Model):
name = models.CharField(max_length=200)
statement = models.TextField()
slug=models.SlugField()
category_name = models.ForeignKey('Category', on_delete=models.CASCADE)
def __str__(self):
return self.name
class Article(models.Model):
author = models.ForeignKey('auth.User', on_delete=models.CASCADE)
title = models.CharField(max_length=200)
slug=models.SlugField()
text = models.TextField()
created_date = models.DateTimeField(
default=timezone.now)
published_date = models.DateTimeField(
blank=True, null=True)
subject_name = models.ForeignKey('Subject', on_delete=models.CASCADE)
def publish(self):
self.published_date = timezone.now()
self.save()
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('blog:detail', kwargs={'id' : self.id})
blog/views.py
def detail(request,article_slug):
article = get_object_or_404(Article, slug=article_slug)
article_list=Article.objects .all()
subject_list = Subject.objects.all()
context={
'article': article,
'article_list':article_list,
'subject_list': subject_list
}
return render(request, 'blog/detail.html', context)
blog/urls.py
url(r'^(?P<category_slug>[\w-]+)/(?P<subject_slug>[\w-]+)/(?P<article_slug>[\w-]+)/$', views.detail, name='detail'),
I want to see the url when I click on the links of my article
http://127.0.0.1:8000/myworkandresearch/category_slug/subject_slug/article_slug
blog / urls.py 'How can I edit?
edit my blog/models.py
class Article(models.Model):
author = models.ForeignKey('auth.User', on_delete=models.CASCADE)
title = models.CharField(max_length=200)
slug=models.SlugField()
text = models.TextField()
created_date = models.DateTimeField(
default=timezone.now)
published_date = models.DateTimeField(
blank=True, null=True)
subject_name = models.ForeignKey('Subject', on_delete=models.CASCADE)
def publish(self):
self.published_date = timezone.now()
self.save()
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('blog:detail', args=[self.slug, self.subject.slug, self.subject.category.slug])
blog/views.py
def detail(request, category_slug, subject_slug, article_slug):
article = Article.objects.filter(
slug = article_slug,
subject__slug = subject_slug,
subject__category__slug = category_slug
)
subject_list = Subject.objects.all()
category_list = Category.objects.all()
context = {
'category_list': category_list,
'subject_list': subject_list,
'article': article
}
return render(request, 'blog/detail.html', context)
blog/urls.py
from django.conf.urls import include, url
from . import views
app_name = 'blog'
urlpatterns = [
url(r'^$', views.myworkandresearch, name='myworkandresearch'),
url(r'(?P<category_slug>[\w-]+)/$', views.subjects, name='subjects'),
url(r'^(?P<category_slug>[\w-]+)/(?P<subject_slug>[\w-]+)/(?P<article_slug>[\w-]+)/$', views.detail, name='detail'),
]
subjects.html
{% for article in subject.article_set.all %}}
<ul class="sidebar-items">
<li>{{article.title}}</li>
</ul>
{% endfor %}
[error continues.][2]
Page not found (404) Request Method: GET Request
URL: http://127.0.0.1:8000/myworkandresearch/machine_learning/python_dictionary/numpy/ Raised by: blog.views.subjects No Category matches the given query.
You're seeing this error because you have DEBUG = True in your Django
settings file. Change that to False, and Django will display a
standard 404 page.
I think you should have a detail view as
def detail(request, category_slug, subject_slug, article_slug):
article = Article.objects.filter(
slug = article_slug,
subject__slug = subject_slug,
subject__category__slug = category_slug
)
return render(request, 'blog/detail.html', {'article': article})
You need the following method on your article model
def get_absolute_url(self):
return reverse('detail', args=[self.slug, self.subject.slug, self.subject.category.slug])
When displaying your articles
{{article.title}}
Your url might look like this
url(r'^myworkandreseach/(?P<category_slug>[\w-]+)/(?P<subject_slug>[\w-]+)/(?P<article_slug>[\w-]+)/$', views.detail, name='detail'),
Be sure to import views

Django reduce queries

I have two models, Post and Vote. Users can upvote and downvote posts.
models.py:
class Post(models.Model):
poster = models.ForeignKey('auth.User')
question = models.ForeignKey('self', null=True, blank=True)
post_title = models.CharField(max_length=300)
post_content = models.TextField(null=True, blank=True)
is_published = models.BooleanField(default=True)
is_locked = models.BooleanField(default=False)
is_question = models.BooleanField(default=True)
is_deleted = models.BooleanField(default=False)
created_date = models.DateTimeField(
default=timezone.now)
published_date = models.DateTimeField(
blank=True, null=True)
date_modified = models.DateTimeField(
blank=True, null=True)
def publish(self):
self.published_date = timezone.now()
self.save()
def __str__(self):
return self.post_title
class Vote(models.Model):
user = models.ForeignKey('auth.User')
post = models.ForeignKey('Post')
vote_type = models.SmallIntegerField()#-1, 0, 1
date_voted = models.DateTimeField(
default=timezone.now)
def __str__(self):
return self.user
I use the following code in my view to return the posts to templates:
views.py:
def index(request):
posts = Post.objects.filter(created_date__lte=timezone.now(
), is_question=1, is_published=1).order_by('-created_date')
#removed the paging stuff here for simplification
return render(request, 'homepage/index.html', {'posts': posts})
This just returns the posts, but I also want to check if the current user has voted or not (and possibly the sum of the vote_type column for each post which is the total number of votes for the post).
Currently I use template tags for each post to check if the current user has voted or not. This creates a lot of queries. (Currently 50 queries with 40 duplicates).
My index.html sample code:
{% for post in posts %}
{% if post|userVotedThisPost:request.user.id == 1 %}
<img id="upvote-img" class="icons" src="{% static 'img/upvote-marked.svg' %}" alt="Upvote">
{% else %}
<img id="upvote-img" class="icons" src="{% static 'img/upvote.svg' %}" alt="Upvote">
{% endif %}
{% endfor %}
Is there any way to query everything in the views.py and then in the template I could check like this: (if post.user_voted), so that the database is not hit each time in the for loop?
You can use prefetch_related to fetch the related votes for that user.
from django.db.models import Prefetch
Post.objects.filter(
created_date__lte=timezone.now(),
is_question=1,
is_published=1
).order_by(
'-created_date',
).prefetch_related(
Prefetch('vote_set', queryset=Vote.objects.filter(user=request.user), to_attr='user_votes')
)
Then in your template, change the check to:
{% if post.user_votes %}

Using Django, How do I return all posts associated with a tag

I'm trying to return all posts associated with a tag using Django. I have searched for a solution but can't find one. I tried to code something but it didn't work. Heres my code
models.py
class Tag(models.Model):
title = models.CharField(max_length=250)
slug = models.SlugField(max_length=200, unique=True)
timestamp = models.DateTimeField(auto_now=False, auto_now_add=True)
updated = models.DateTimeField(auto_now=True, auto_now_add=False)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse("posts:tag_index", kwargs={"slug": self.slug})
class Meta:
ordering = ["-timestamp"]
class Post(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, default=1)
slug = models.SlugField(unique=True)
title = models.CharField(max_length=120)
image = models.ImageField(upload_to=upload_location, null=True, blank=True,
width_field="width_field",
height_field="height_field")
height_field = models.IntegerField(default=0)
width_field = models.IntegerField(default=0)
content = models.TextField()
draft = models.BooleanField(default=False)
publish = models.DateField(auto_now=False, auto_now_add=False)
timestamp = models.DateTimeField(auto_now=False, auto_now_add=True)
updated = models.DateTimeField(auto_now=True, auto_now_add=False)
tags = models.ManyToManyField(Tag)
objects = PostManager()
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse("posts:detail", kwargs={"slug": self.slug})
class Meta:
ordering = ["-timestamp"]
posts/urls.py
from .views import post_list, post_create, post_detail, post_update, post_delete, sewp, tag_detail
urlpatterns = [
url(r'^$', post_list, name='list'),
url(r'^tag/(?P<slug>[\w-]+)/$', tag_detail, name="tag_index"),
url(r'^create/$', post_create, name='create'),
url(r'^sewp$', sewp, name='sewp'),
url(r'^(?P<slug>[\w-]+)/$', post_detail, name='detail'),
url(r'^(?P<slug>[\w-]+)/edit/$', post_update, name='update'),
url(r'^(?P<id>\d+)/delete/$', post_delete, name='delete'),
]
views.py
def tag_detail(request, slug=None):
query = slug
queryset_list = Post.objects.active()
tags_list = queryset_list.filter(tags__icontains=query).distinct()
instance = get_object_or_404(Tag, slug=slug)
context = {
"instance": instance,
"tags_list": tags_list
}
return render(request, "posts/tag_index.html", context)
tag_index.html
{% extends 'posts/base.html' %}
{% block content %}
{{ instance }}
{{ tags_list }}
{% endblock content %}
I just want to return all the tags and paginate it.
and can I modify the following code to paginate my results :
paginator = Paginator(queryset_list, 2) # Show 25 contacts per page
page_request_var = "page"
page = request.GET.get(page_request_var)
try:
queryset = paginator.page(page)
except PageNotAnInteger:
# If page is not an integer, deliver first page.
queryset = paginator.page(1)
except EmptyPage:
# If page is out of range (e.g. 9999), deliver last page of results.
queryset = paginator.page(paginator.num_pages)
context = {
"queryset": queryset,
"title": "Posts",
"page_request_var": page_request_var,
"today": today,
"queryset_list": queryset_list,
"paginator": paginator,
}
any guidance or help on this will be appreciated
If you want to find all Posts associated with a tag, simply use:
posts = Post.objects.filter(tag__title = query)
This will return all posts with the tag specified by the query string.
Read more about making queries here: https://docs.djangoproject.com/en/1.9/topics/db/queries/
I would use a generic ListView like so:
from django.views.generic.list import ListView
from django.shortcuts import get_object_or_404
class TagView(ListView):
template_name = 'posts/tag_index.html'
def get_queryset(self):
""" get the Tag object or return 404 """
self.tag = get_object_or_404(Tag, slug=self.kwargs['slug'])
return Post.objects.filter(tag=self.tag)
def get_context_data(self, **kwargs):
""" add a posts variable to context to use in template """
context = super(TagView, self).get_context_data(**kwargs)
context['posts'] = Post.objects.filter(tag=self.tag)
This is the syntax based on views.py structure
views.py:
def tag_index(request, slug=None):
instance = get_object_or_404(Tag, slug=slug)
ins = instance.post_set.all()
context = {
"instance": ins,
}
return render(request, "posts/tag_list.html", context)
then in the tags_list.html
{% for i in instance %}
{{ i.title }}
{{ i.content }}
{% endfor %}
hope this helps somebody

Categories