I'm hoping this is a very simple issue and I'm over complicating it. Lets say I have two models (movie and checkin). When updating a checkin object, I receive an error "Movie matching query does not exist", however creating works perfectly fine.
Models
class Movie(models.Model):
title = models.CharField(max_length=150)
genre = models.CharField(max_length=25)
description = models.TextField()
slug = models.SlugField()
class Meta:
ordering = ["title"]
def get_absolute_url(self):
return reverse("movie_detail", args=[str(self.slug)])
def __str__(self):
return self.title
class Checkin(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
movies = models.ForeignKey(
Movie,
on_delete=models.CASCADE,
related_name="checkins",
)
notes = models.TextField(max_length=255, blank=True)
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
related_name="checkins",
null=True,
blank=True,
)
class Meta:
ordering = ["-added_date"]
def __str__(self):
return f"{self.user} checked into {self.movies.title} on {self.added_date}"
def get_absolute_url(self):
return reverse("checkin_detail", args=[str(self.id)])
The goal for my checkin views is to create a checkin based on the slug from the details page of the movie object. This way the user does not have to scroll through hundreds of movie objects just to find the one they are interested in. I am using get_form_kwargs() to accomplish this (which could be the problem but couldn't figure out a better way to accomplish this).
class CheckinCreateView(CreateView):
model = Checkin
template_name = "checkin/checkin_create.html"
context_object_name = "checkin_create"
form_class = CheckinForm
success_url = reverse_lazy("dashboard")
def get_form_kwargs(self):
kwargs = super(CheckinCreateView, self).get_form_kwargs()
if kwargs["instance"] is None:
kwargs["instance"] = Checkin()
kwargs["instance"].movies = Movie.objects.get(slug=self.kwargs["slug"])
kwargs["instance"].user = self.request.user
return kwargs
The above CheckinCreateView works fine. On the MovieDetailView, I am able to create a checkin, and the movies field is instantiated with the Movie object's from the MovieDetailView and save the object to my database. However, now when I trying to update that checkin object, I get the error "Movie matching query does not exist".
class CheckinUpdateView(UpdateView):
model = Checkin
template_name = "checkin/checkin_update.html"
context_object_name = "checkin_update"
form_class = CheckinForm
success_url = reverse_lazy("dashboard")
# def get_form_kwargs(self):
# kwargs = super(CheckinUpdateView, self).get_form_kwargs()
# if kwargs["instance"] is None:
# kwargs["instance"] = Checkin()
# kwargs["instance"].movies = self.object.movies
# kwargs["instance"].user = self.request.user
# return kwargs
# def form_valid(self, form):
# # Add user to form
# obj = form.save(commit=False)
# obj.movies = self.object.movies
# obj.user = self.request.user
# obj.save()
# return super(CheckinUpdateView, self).form_valid(form)
When updating the checkin object, the movie object is in the movies field (so its clear it exists), but I still get the error message "Movie matching query does not exist" and I noticed that its failing on the CheckinCreateView's
kwargs["instance"].movies = Movie.objects.get(slug=self.kwargs["slug"])
So my question is kind of two parts
Question A: How do I properly, from the MoviesDetailView, create an object using the CheckinCreateView with or without get_form_kwargs() so I can reference the object properly when updating
or
Question B: How do I reference the Movie object when using CheckinUpdateView without sending the user back to the MovieDetailView
Heres my Movie views in case thats needed as well
class MovieDetailView(FormMixin, DetailView):
model = Movie
template_name = "movie/movie_detail.html"
context_object_name = "movie_detail"
form_class = CommentForm
def get_success_url(self):
return reverse_lazy("movies_detail", kwargs={"slug": self.object.slug})
def get_context_data(self, *args, **kwargs):
context = super(MovieDetailView, self).get_context_data(*args, **kwargs)
context["comment_form"] = self.get_form()
return context
def post(self, request, *args, **kwargs):
self.object = self.get_object()
template = "movie/movie_detail.html"
comment_form = self.get_form()
context = {"comment_form": comment_form}
if comment_form.is_valid():
return self.form_valid(comment_form)
return render(request, template, context=context)
def get_form(self, *args, **kwargs):
return super(MovieDetailView, self).get_form(*args, **kwargs)
def form_valid(self, form):
new_comment = form.save(commit=False)
new_comment.movies = self.object
new_comment.user = self.request.user
new_comment.save()
return super(MovieDetailView, self).form_valid(new_comment)
In movie_detail.html, I am getting to the CheckinForm with the following
<a href="{% url 'checkin_create' request.resolver_match.kwargs.slug %}"> Check-in </a>
question from:
https://stackoverflow.com/questions/65646756/django-3-updateview-movie-matching-query-does-not-exist-when-using-2-models