I can't get my redirect to work correctly after updating a bicycle in my Django app.
When I use my bikes_update() method and update the bicycle profile, if my redirect is just to '/bikes', I'm taken back to the bicycle collection/bicycles owned with no issue. But when I try and redirect back to the profile of the bike I just editted, I get the error that my return pathway doesn't match any of the url patterns. Even though that's the same pathway that initially takes me to the bicycle profile view (not the same one where I edit the bicycle, that is a different view).
I've pasted the bikes_update() method here:
def bikes_update(request, bike_id):
if request.method != 'POST' or 'user_id' not in request.session:
return redirect("/")
this_bike = Bike.objects.filter(id=bike_id).update(
name = request.POST['bike_name'],
model = request.POST['model_id'],
)
return redirect('/bikes')
return redirect('/bikes/<int:bike_id>')
return redirect('/bikes/<int:bike_id>/')
I obviously only use one of the redirects, not all the three in the final block. But I can't figure out why at least one of the final two do not work. When I have the bottom two redirects commented out, the 'return redirect('/bikes')' line works fine, but it takes me to the page listing all of my bikes when I want to go back the profile of the bike I just editted so I don't have to navigate back to it from the bicycle collection. Navigating to /bikes/int:bike_id/ works fine when going to the profile initially from the list of bikes, but after I finishing editing I run into this error even though it's the same line as what got me to the profile in the first place. As soon as I click the submit button and try to redirect back to /bikes/int:bike_id/ I get my error.
I'm able to update the bicycle profile correctly, so it's something to do with this redirect, but I don't get it.
I don't understand how line 12 in my screen snippet and the current path (both highlighted in the image), aren't the same/don't match.
CodePudding user response:
If you want to redirect on /bikes/<int:bike_id>/
then you can use a format string like this...
def bikes_update(request, bike_id):
if request.method != 'POST' or 'user_id' not in request.session:
return redirect("/")
this_bike = Bike.objects.filter(id=bike_id).update(
name = request.POST['bike_name'],
model = request.POST['model_id'],
)
return redirect(f'/bikes/{bike_id}/')
CodePudding user response:
You have to add the id here not this "int:bike_id". put your id variable here like this redirect(f'/bikes/{Id}').
CodePudding user response:
redirect
can take a model as an argument, so you could do something like:
def bikes_update(request, bike_id):
if request.method != 'POST' or 'user_id' not in request.session:
return redirect("/")
this_bike = Bike.objects.filter(id=bike_id).update(
name = request.POST['bike_name'],
model = request.POST['model_id'],
)
this_bike = get_object_or_404(Bike, pk=bike_id)
return redirect(this_bike)
You will need a get_absolute_url
method in your models.py though. For example:
def get_absolute_url(self):
return reverse("bikes", kwargs={"pk": self.pk})
This can be used for other things in Django as well (including usage in templates).
More info here: Django Docs
Of course, as you're obtaining the object now for this purpose, you may want to consider refactoring (not using a queryset update and perhaps changing the this_bike
attributes instead) how you update it in the first place, as you're only dealing with a single object here.