Home > Back-end >  Using urls path with slug returns Page not found (404) No profile found matching the query
Using urls path with slug returns Page not found (404) No profile found matching the query

Time:05-26

I'm trying to create user Profile for my django project, I'm using UpdateView to allow user to edit Profile model when they want to create profile for their account but it return an error every time I click on create profile url in the profile template.

Profile Template:

<div >
    <div >
        {% for profile in profiles %}
        <div >
            <a href="{{profile.website}}">{{profile.website}}</a>
            <a href="{{profile.twitter}}">{{profile.website}}</a>
        </div>
        {% endfor %}
    </div>
</div>
<br>
<div >
    <div >
        <a href="{% url 'editProfile' user.id %}" >Create Profile</a>
    </div>
</div>

My model:

class Profile(models.Model):
    user = models.OneToOneField(User,on_delete=models.CASCADE)
    profile_image = models.ImageField(upload_to="avatars/")
    stories = models.TextField(max_length=500,blank=True, null=True)
    website = models.URLField(max_length=250, blank=True, null=True)
    twitter = models.URLField(max_length=250, blank=True, null=True)
    location = models.CharField(max_length=50, blank=True, null=True)
    slug = models.SlugField(blank=True, null=True)

my urls:

path('editprofile/<slug:slug>/edit', views.EditProfileView.as_view(), name='editProfile'),

my views:

@login_required(login_url='login')
def profile(request, pk):
    profiles = Profile.objects.filter(user=request.user)
    questions = Question.objects.filter(user=request.user)
    context = {'questions':questions, 'profiles':profiles}
    return render(request, 'profile.html', context)

class EditProfileView(UpdateView):
    model = Profile
    fields = ['profile_image', 'stories', 'website', 'twitter', 'location']
    template_name = 'edit_profile.html'
    success_url = reverse_lazy('index')

    def save(self, *args, **kwargs):
        self.slug = slugify(self.user)
        super(Creator, self).save(*args, **kwargs)

CodePudding user response:

Firstly fix

  def save(self, *args, **kwargs):
        self.slug = slugify(self.user.field) #field is what you want to slugfiy 
        super(Creator, self).save(*args, **kwargs)

secondly

You are sending ID but url requires slug

  #old
  <a href="{% url 'editProfile' user.id %}" >Create Profile</a>

  #should be
  <a href="{% url 'editProfile' user.slug_field %}" >Create Profile</a>

CodePudding user response:

You have made user a OneToOneField in your Profile model, that means you should not use filter() in profile view, you should use get_object_or_404 for getting single user's profile, as it has OneToOneRelation.

Try this:

from django.shortcuts import get_object_or_404
@login_required(login_url='login')
def profile(request, pk):
    profile = get_object_or_404(Profile,user=request.user)
    questions = Question.objects.filter(user=request.user)
    context = {'questions':questions, 'profile':profile}
    return render(request, 'profile.html', context)

class EditProfileView(UpdateView):
    model = Profile
    fields = ['profile_image', 'stories', 'website', 'twitter', 'location']
    template_name = 'edit_profile.html'
    success_url = reverse_lazy('index')

    def save(self, *args, **kwargs):
        self.slug = slugify(self.user)
        super(Creator, self).save(*args, **kwargs)


def index(request):
    return render(request, 'index.html')

profile.html:

    <div >
        <div >
            {% comment %} {% for profile in profiles %} {% endcomment %}
            <div >
                <a href="{{profile.website}}">{{profile.website}}</a>
                <a href="{{profile.twitter}}">{{profile.website}}</a>
            </div>
            {% comment %} {% endfor %} {% endcomment %}
        </div>
    </div>
    <br>
    <div >
        <div >
            <a href="{% url 'editProfile' profile.slug %}" >Create Profile</a>
        </div>
    </div>

Note: I have passed profile.slug since the EditProfileView also requires slug to come in route.

Note: You should not run loop while displaying data with single object.

index.html (success template):

<body>
<h3>Profile updated successfully.</h3>
</body>

edit_profile.html

<body>
    <h2>You can edit your profile </h2>
    <form method="post">
        {% csrf_token %}
        {{ form.as_p }}
        <input type="submit" value="Save">
    </form>
</body>

That will successfully update your profile.

  • Related