I'm working on a Django app similar to some streaming platforms, as I am building a portfolio.
In the database management part (where I add, edit or delete films), I'm trying to use UpdateView (as I did on other projects) to update the films informations.
The link works, I go to the edit page where the form is populated with the already existing informations, but when I save after an edit, I got my message 'This film is already in the database', a message I created that should only appears when I add a film (with a modal and an API call). It's not even in the same view. I've tried everything I could, but I'm still stuck.
What I am trying to understand is what happens when I click on the save button. It looks like it redirects to the ManageFilmsView where it tries to create a new entrance to the database. Which is weird, as it is called UpdateView. Should I overwrite something in the UpdateView?
What can I try next?
Here is my views :
class ManageFilmsView(FormView, ListView):
model = Film
template_name = "manage-films.html"
context_object_name = "films"
form_class = AddFilmForm
success_url = reverse_lazy("manage_films")
def get_queryset(self):
parameter = self.kwargs.get("letter") if self.kwargs.get("letter") else "a"
return Film.objects.filter(title__startswith=parameter)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
letters = list(string.ascii_uppercase)
context["letters"] = letters
context["selected_letter"] = (
self.kwargs.get("letter") if self.kwargs.get("letter") else "a"
)
return context
def form_valid(self, form):
search_title = form.cleaned_data["title"].replace(" ", "+")
search_year = form.cleaned_data["year"]
response = requests.get(
f"http://www.omdbapi.com/?apikey={api_key}&t={search_title}&y={search_year}"
)
response.raise_for_status()
film_data = response.json()
if Film.objects.filter(title=film_data["Title"]).exists():
messages.add_message(
self.request,
messages.INFO,
f"This film is already present in the database.",
)
else:
film = Film(
title=film_data["Title"],
year=film_data["Year"],
genre=film_data["Genre"],
country=film_data["Country"],
director=film_data["Director"],
actors=film_data["Actors"],
runtime=film_data["Runtime"],
poster=film_data["Poster"],
plot=film_data["Plot"],
)
film.save()
messages.add_message(
self.request,
messages.SUCCESS,
f"{ film.title } successfully added to the database.",
)
return HttpResponseRedirect(self.get_success_url())
def form_invalid(self, form):
messages.add_message(self.request, messages.ERROR, "Something went wrong.")
return HttpResponseRedirect(self.get_success_url())
class FilmsListView(ListView):
model = Film
context_object_name = "films"
template_name = "manage-films-list.html"
def get_queryset(self):
parameter = self.kwargs.get("letter") if self.kwargs.get("letter") else "a"
return Film.objects.filter(title__startswith=parameter)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
letters = list(string.ascii_uppercase)
context["letters"] = letters
context["selected_letter"] = (
self.kwargs.get("letter") if self.kwargs.get("letter") else "a"
)
return context
class FilmEditView(UpdateView):
model = Film
fields = [
"title",
"year",
"genre",
"country",
"director",
"actors",
"runtime",
"poster",
"trailer",
"plot",
"why",
]
template_name = "edit-film.html"
success_url = reverse_lazy("films_list")
Here is my urls
urlpatterns = [
path("", ManageFilmsView.as_view(), {"letter": None}, name="manage_films"),
]
htmxpatterns = [
path("<str:letter>", FilmsListView.as_view(), name="films_list"),
path("edit/<int:pk>", FilmEditView.as_view(), name="edit_film"),
path("delete/<int:pk>", DeleteFilmView.as_view(), name="delete_film"),
]
urlpatterns += htmxpatterns
Here is a shorter version of the edit-film.html :
{% load widget_tweaks %}
<h2 class="text-xl my-4 ml-10 p-4">Here are the details to edit the informations about the film "{{ film.title }}"</h2>
<form action="" action="" class="w-3/5 ml-10 flex flex-col" method="POST">
{% csrf_token %}
<div class="mb-4">
<label class="mb-1 text-gray-100">{{ form.title.label|upper }}</label>
{% render_field form.title class="bg-gray-50 border border-gray-300 text-gray-950 text-lg rounded-lg block w-full p-2.5 dark:bg-gray-600 dark:border-gray-500 dark:placeholder-gray-400 dark:text-white" %}
</div>
<div class="mb-4">
<label class="mb-1 text-gray-100">{{ form.genre.label|upper }}</label>
{% render_field form.genre class="bg-gray-50 border border-gray-300 text-gray-950 text-lg rounded-lg block w-full p-2.5 dark:bg-gray-600 dark:border-gray-500 dark:placeholder-gray-400 dark:text-white" %}
</div>
<button type="submit" value="Update" class="w-1/4 mt-2 mb-20 text-gray-100 bg-gray-900 hover:bg-gray-950 dark:bg-gray-600 dark:hover:bg-red-900 font-medium rounded-lg text-sm px-5 py-2.5 text-center place-items-center">SAVE</button>
</form>
I used ChatGPT and after a long conversation, I changed my
success_url
toand then
and it works. I'm pretty sure I tried it, but the problem is gone.