对于我的一个开源项目,我需要创建一个添加/编辑页面,以便一次保存即可编辑多个记录。
回购是为学习目的而形成的IMDB克隆。用户可以在自己的个人资料中添加自己喜欢的类型。然后,形成一个编辑页面,以显示这些喜欢的流派和该流派中的电影的列表。 (此处为for循环)用户可以为这些电影添加注释,观看列表选项等。 (不是表单集)
但是,代码无法按预期运行。该页面无法保存,只能更改列表的第一个复选框。
没有错误。
注意:
# users/templates/user-movies-with_loop.html
{% extends 'base.html' %}{% load crispy_forms_tags %}
<!-- Title -->
{% block htitle %}Your movies from favorite genres{% endblock %}
{% block title %}Your movies from favorite genres{% endblock %}
{% block content %}
<div class="card card-signin">
{% include 'users/profile-menu.html' %}
<h3 class="card-title text-center my-4">Take notes for your movies <small></small></h3>
<hr class="mb-1">
<div class="card-body">
<form method="POST">
{% csrf_token %}
{% for genre in user.genres.all %}
<h2 for="genre" name="genre" value="{{ genre.id }}">{{ genre.name }}</h2>
{% for movie in genre.movies.all %}
<div class="ml-5">
<h4>{{ movie.title }}</h4>
{{ form|crispy }}
</div>
<input type="hidden" name="user" value="{{ user.id }}">
<input type="hidden" name="movie" value="{{ movie.id }}">
{% empty %}
<p class="alert alert-danger">The genre you have selected on your profile doesn't have any movies!</p>
{% endfor %}
{% empty %}
<p class="alert alert-danger">You should select genres with movies from your profile to edit here!</p>
{% endfor %}
<input class="btn btn-lg btn-primary btn-block text-uppercase" type="submit" value="Submit">
</form>
</div>
</div>
{% endblock %}
# users.forms.py
...
class UserMovieFormWithLoop(ModelForm):
genre = forms.HiddenInput(attrs={'disabled': True})
class Meta:
model = UserMovie
fields = ('user', 'movie', 'note', 'watched', 'watch_list')
widgets = {
'user': forms.HiddenInput,
'movie': forms.HiddenInput,
'watched': forms.CheckboxInput(),
}
...
# users.models.py
...
class UserMovie(models.Model):
"""
Users have notes about their favorite movies.
"""
user = models.ForeignKey(User, on_delete=models.CASCADE)
movie = models.ForeignKey('movies.Movie', default=1, on_delete=models.CASCADE)
note = models.CharField(max_length=250, null=True, blank=True)
watched = models.BooleanField(default=False, verbose_name='Have you seen before?')
watch_list = models.BooleanField(default=False, verbose_name='Add to Watch List?')
def __str__(self):
return f'{self.user.username} ({self.movie.title})'
...
# users.views.py
...
class UserMovieViewWithLoop(LoginRequiredMixin, CreateView):
model = UserMovie
template_name = 'users/user-movies-with_loop.html'
form_class = UserMovieFormWithLoop
success_message = 'your form has been submitted.'
success_url = reverse_lazy('users:user_movies2')
def form_valid(self, form):
user = self.request.user
movie_counter = Movie.objects.filter(genres__in=user.genres.all()).count()
f = form.save(commit=False)
f.user = user
for i in range(movie_counter):
f.pk = None
f.save()
return super().form_valid(form)
def get_context_data(self, **kwargs):
context = super(UserMovieViewWithLoop, self).get_context_data(**kwargs)
context['form'] = self.form_class
return context
def get_object(self):
user = self.request.user
return UserMovie.objects.get(user=user)
...