pythondjangodjango-viewsdjango-templatesdjango-profiles

Profile page is showing error under postlist href since pk number is increasing?


in blog page, i have made profile pages link for every user. there is also a view for userlist where users linked to their own profile page.

here is my blog/models.py:

class Post(models.Model):
    title = models.CharField(max_length=255)
    body=RichTextField(blank=True,null=True)
    image=models.FileField(upload_to="mediaphoto",validators=[validate_file_size])
    topImage=ImageSpecField(source='image',processors=[ResizeToFill(750,300)],format='PNG',options={'quality':60})  
    date = models.DateTimeField(auto_now_add=True)
    author = models.ForeignKey(User,on_delete=models.CASCADE)
    category=models.ForeignKey(Category,on_delete=models.CASCADE)
    def __str__(self):
        return self.title
    def get_absolute_url(self):
        return reverse('post_detail', args=[str(self.id)])
    

blog/views.py:

class CustomContentMixin:
    def get_context_data(self, **kwargs):
        context = super(CustomContentMixin, self).get_context_data(**kwargs)
        context['user_list']= Profile.objects.all()
        context['category_list']=Category.objects.all()
        return context


class BlogappListView(CustomContentMixin,ListView):
    model = Category,Profile
    template_name = 'home.html'
    context_object_name='post_list'
    queryset=Post.objects.all()
    paginate_by=7
    
   
class BlogappUpdateView(CustomContentMixin,UpdateView,LoginRequiredMixin,UserPassesTestMixin):
    model=Post
    template_name='post_edit.html'
    fields=('title','body','image','category')
    login_url='login'   
    def test_func(self): 
        obj = self.get_object()
        return obj.author == self.request.user
    
class BlogappDetailView(DetailView,LoginRequiredMixin,FormMixin):
    model=Post
    template_name='post_detail.html'
    login_url='login'
    form_class=CommentForm
    def get_success_url(self):
        return reverse_lazy('post_detail', kwargs={'pk': self.object.pk})
    def get_context_data(self, **kwargs):
        context = super(BlogappDetailView, self).get_context_data(**kwargs)
        context['comments']=Comment.objects.filter(post=self.object)
        context['comment_form']=CommentForm()
        context['user_list']= Profile.objects.all()
        context['category_list']=Category.objects.all()
        return context
    def post(self, request, *args, **kwargs):
        self.object = self.get_object()
        comment_form = self.get_form()
        if comment_form.is_valid():
            return self.form_valid(comment_form)
        else:
            return self.form_invalid(comment_form)

    def form_valid(self, comment_form):
        comment_form.instance.post = self.object
        comment_form.instance.author=self.request.user
        comment_form.save()
        return super().form_valid(comment_form)
       

class BlogappDeleteView(CustomContentMixin,DeleteView,LoginRequiredMixin,UserPassesTestMixin):
    model=Post
    template_name='post_delete.html'
    success_url=reverse_lazy('home')
    login_url='login'
    def test_func(self): 
        obj = self.get_object()
        return obj.author == self.request.user
    
class BlogappCreateView(CustomContentMixin,CreateView,LoginRequiredMixin):
    model=Post
    template_name='post_new.html'
    login_url='login'
    fields=('title','body','image','category')
    def form_valid(self, form):
        form.instance.author = self.request.user
        return super().form_valid(form)

acounts/models.py:

class Profile(models.Model):
    
    user = models.OneToOneField(User,on_delete=models.CASCADE,primary_key=True)
    name=models.CharField(max_length=30, blank=True)
    bio = models.TextField(max_length=500, blank=True)
    location = models.CharField(max_length=30, blank=True)
    birthdate = models.DateField(null=True, blank=True)
    def __str__(self):
        return self.user.username
@receiver(post_save, sender=User)
def user_is_created(sender, instance, created, **kwargs):
    
    if created:
        Profile.objects.create(user=instance)
    else:
        instance.profile.save()

accounts/views.py:

class ProfileDetailView(DetailView):
    template_name='profile.html'
    model=Profile
    def get_user_profile(self,pk):
        return get_object_or_404(Profile,pk=pk)
    
        
class ProfileEditView(UpdateView):
    model=Profile
    template_name='profile_edit.html'
    form_class=ProfileForm
    success_url = reverse_lazy('profile')
    def get_user_profile_edit(self,pk):
        return get_object_or_404(Profile,pk=pk)

accounts/urls.py:

urlpatterns = [
    .............
    path('profile/<int:pk>/', ProfileDetailView.as_view(), name='profile'),
    path('profile/<int:pk>/edit', ProfileEditView.as_view(), name='profile_edit'),
    ]

now for base.html here is my userlist portion which only shows the userlist linked to their profile page link:

{% for user in user_list %}
                <ul>
                  
                    <a class="user" href="{% url 'profile' user.pk %}" >{{ user }}</a>
                  
                </ul>
              {% endfor %}

now for home.html where post list is shown with their author link:

{% block content %}
{% for post in post_list %}
<!-- Blog Post -->
<div class="card mb-4">
 <img class="card-img-top" src="{{post.topImage.url}}" alt="Card image cap">
  <div class="card-body">
    <h2 class="card-title">{{post.title}}</h2>
    <p class="card-text">{{post.body|truncatechars:400|safe}}</p>

    <a href="{% url 'post_detail' post.pk %}" class="btn btn-primary">Read More &rarr;</a>
  </div>
  <div class="card-footer text-muted">
    Posted on {{post.date|safe}} by
    <a href="{% url 'profile' post.pk %}" >{{post.author}}</a>
    in <a href="{% url 'category_list' post.category.pk %}">{{post.category}}</a> 
  </div>
</div>
{% endfor %}  

{% endblock content %}

here is the profile.html:

{% block content %}


<p>Name: {{ object.name }}  .</p>
<p>Bio: {{ object.bio }} .</p>
<p>Location: {{ object.location }} .</p>
<p>Date of birth: {{ object.birthdate }} .</p>
<p>Gender: {{ object.gender }} .</p>
<p><a class="btn btn-warning" href="{% url 'home' %}">homepage</a></p>
<p><a class="btn btn-warning" href="{% url 'profile_edit' object.pk %}">Edit Profile</a></p>

{% endblock %}

The main problem is when click on the each author in post list, it redirects me to http://localhost:8000/profile/3/, http://localhost:8000/profile/4/, http://localhost:8000/profile/5/ and so on which means when i add a new post it just increasing the profile pk number. but the profile pk number should be fixed according to their profile url. and the profile page takes me to the following error as the profile page relevant to pk doesnot exit:

Page not found (404)
Request Method: GET
Request URL:    http://localhost:8000/profile/4/
Raised by:  accounts.views.ProfileDetailView
No profile found matching the 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.

what is my mistake here? and how can i fix this so that i can show profile page relevant to post author?

and please let me know if you need further information.


Solution

  • In home.HTML file the following thing would solve the problem:

    <a href=“{% url ‘profile’ post.author.profile.pk %}”>{{post.author}}</a>
    

    This line would do the trick.