I'm learning django, whenever I click on the profiles(links) on the profile_list page, I get the profile doesn't exist error it always goes to profiles that do not longer exist in the database.
Models.py:
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver
# Create your models here.
class Profile(models.Model):
user=models.OneToOneField(User,on_delete=models.CASCADE)
follows=models.ManyToManyField(
"self",
related_name="followed_by",
symmetrical=False,
blank=True)
def __str__(self):
return self.user.username
@receiver(post_save,sender=User)
def create_profile(sender, instance, created, **kwargs):
if created:
user_profile=Profile(user=instance)
user_profile.save()
user_profile.follows.add(instance.profile)
user_profile.save()
admin.py:
from django.contrib import admin
from django.contrib.auth.models import Group,User
from .models import Profile
class ProfileInline(admin.StackedInline):
model=Profile
class UserAdmin(admin.ModelAdmin):
model=User
fields=["username"]
inlines=[ProfileInline]
# Register your models here.
admin.site.unregister(Group)
admin.site.unregister(User)
admin.site.register(User,UserAdmin)
views.py:
from django.urls import reverse
from django.shortcuts import render
from requests import request
from users.models import Profile
from django.http import HttpResponseRedirect
# Create your views here.
def dashboard(request):
return render(request,"inbox/layout.html")
def feed(request):
return render(request,"inbox/feed.html")
def outbox(request):
return render(request,"inbox/outbox.html")
def profile_list(request):
profiles=Profile.objects.exclude(user=request.user)
return render(request,"inbox/profile_list.html",{"profiles":profiles})
def profile(request, pk):
if not hasattr(request.user, 'profile'):
missing_profile = Profile(user=request.user)
missing_profile.save()
profile = Profile.objects.get(pk=pk)
if request.method == "POST":
current_user_profile = request.user.profile
data = request.POST
action = data.get("follow")
if action == "follow":
current_user_profile.follows.add(profile)
elif action == "unfollow":
current_user_profile.follows.remove(profile)
current_user_profile.save()
return render(request, "inbox/profile.html", {"profile": profile})
profile.html:
<!-- inbox/templates/inbox/profile_list.html -->
{% extends 'inbox/layout.html' %}
{% block content %}
<form method="post">
{% csrf_token %}
<div >
<p>@{{ profile.user.username|upper }}</p>
<div >
{% if profile in user.profile.follows.all %}
<button >Follow</button>
<button name="follow" value="unfollow">
Unfollow
</button>
{% else %}
<button name="follow" value="follow">
Follow
</button>
<button >Unfollow</button>
{% endif %}
</div>
<p1>following:</p1>
<ul>
{% for following in profile.follows.all %}
<li><a href="{% url 'inbox:profile' pk=following.pk %}">{{ following }}</a></li>
{% endfor %}
</ul>
<p2>followers:</p2>
<ul>
{% for follower in profile.followed_by.all %}
<li><a href="{% url 'inbox:profile' pk=follower.pk %}">{{ follower }}</a></li>
{% endfor %}
</ul>
</div>
</form>
{% endblock content %}
profile_list.html template:
<!-- inbox/templates/inbox/profile_list.html -->
{% extends 'inbox/layout.html' %}
{% block content %}
<form method="post">
{% csrf_token %}
{% for profile in profiles %}
<div >
<p>{{ profile.user.username }}</p>
<p><a href="{% url 'inbox:profile' pk=profile.user.pk %}">@{{ profile.user.username|lower }}</a></p>
</div>
{% endfor %}
</form>
{% endblock content %}
CodePudding user response:
You need to match Profile's
pk with profile = Profile.objects.get(pk=pk)
, currently you mentioned the pk of User
model, which matched the given queryset in profile
view, so try sending pk of profile in profile_list.html
template:
{% for profile in profiles %}
<div >
<p>{{ profile.user.username }}</p>
<p><a href="{% url 'profile' pk=profile.pk %}">@{{ profile.user.username|lower }}</a></p>
</div>
{% endfor %}
Also, it is better to use get_object_or_404
instead of , as it calls get() on a given model manager, but it raises Http404 instead of the model’s DoesNotExist exception.get
So, views.py:
def profile(request, pk): if not hasattr(request.user, 'profile'): missing_profile = Profile(user=request.user) missing_profile.save() profile = get_object_or_404(Profile, pk=pk) if request.method == "POST": current_user_profile = request.user.profile data = request.POST action = data.get("follow") if action == "follow": current_user_profile.follows.add(profile) elif action == "unfollow": current_user_profile.follows.remove(profile) current_user_profile.save() return render(request, "home/profile.html", {"profile": profile})
Now, if the profile does not exist, it will show no Profile matches the given query.