Я новичок в Django и с трудом выясняю, как получить модельную форму для сохранения в моей БД.Я следил за некоторыми учебниками / книгами и тратил много времени на SO, и я просто не могу понять эту часть.Приведенные ниже примеры книг приводят создание веб-сайта типа IMDB, где пользователь может голосовать за качество фильмов (в моем примере это были игры).
python v. 3.6.7, django v. 2.1.3, postgresv. 2.2.2
Вот модель, которую я пытаюсь сохранить, и связанный менеджер
class VoteManager(models.Manager):
def get_vote_or_unsaved_blank_vote(self, game, user):
try:
vote = Vote.objects.get(game=game, user=user)
return vote
except self.model.DoesNotExist:
vote = Vote(game=game, user=user)
return vote
class Vote(models.Model):
objects = VoteManager()
value = models.FloatField()
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
game = models.ForeignKey(Game, on_delete=models.CASCADE,)
voted_on = models.DateTimeField(auto_now=True)
class Meta:
unique_together = ('user', 'game')
Теперь форма модели, которую я пытаюсь использовать, чтобы попытаться сохранить эту
class VoteForm(forms.ModelForm):
user = forms.ModelChoiceField(widget=forms.HiddenInput, queryset=get_user_model().objects.all(), disabled=True)
game = forms.ModelChoiceField(widget=forms.HiddenInput, queryset=Game.objects.all(), disabled=True)
value = forms.FloatField()
class Meta:
model = Vote
fields = ('user', 'game', 'value')
Шаблон, который я использую для отображения этой информации.
{% block main %}
<h1>{{ object }}</h1>
<p class="lead">
{{ object.summary }}
</p>
{% endblock %}
{% block sidebar %}
{# rating div omitted #}
<div>
{% if vote_form %}
<form
method="post"
action="{{ vote_form_url }}" >
{% csrf_token %}
{{ vote_form.as_p }}
<button
class="btn btn-primary" >
Vote
</button >
</form >
<h3>Score: {{ object.score|default_if_none:"No score yet!" }}</h3>
{% else %}
<p >Log in to vote for this game</p >
{% endif %}
</div >
{% endblock %}
Наконец, представления для объединения всех этих частей
class GameDetail(DetailView):
queryset = Game.objects.all_with_related_persons_and_score()
def post(self, request, *args, **kwargs):
return redirect('core:CreateVote', game_id=kwargs['pk'])
def get_context_data(self, **kwargs):
ctx = super().get_context_data(**kwargs)
if self.request.user.is_authenticated:
vote = Vote.objects.get_vote_or_unsaved_blank_vote(game=self.object, user=self.request.user)
if vote.id:
vote_form_url = reverse('core:UpdateVote', kwargs={'game_id': vote.game.id, 'pk': vote.id})
else:
vote_form_url = reverse('core:CreateVote', kwargs={'game_id': self.object.id})
ctx['vote_form'] = VoteForm(instance=vote)
ctx['vote_from_url'] = vote_form_url
return ctx
class CreateVote(LoginRequiredMixin, CreateView):
form_class = VoteForm
def get_initial(self):
initial = super().get_initial()
initial['user'] = self.request.user.id
initial['game'] = self.kwargs['game_id']
return initial
def get_success_url(self):
print('never called?')
game_id = self.kwargs['game_id']
return reverse('core:GameDetail', kwargs={'pk': game_id})
def render_to_response(self, context, **response_kwargs):
game_id = self.kwargs['game_id']
game_detail_url = reverse('core:GameDetail', kwargs={'pk': game_id})
return redirect(to=game_detail_url)
В настоящее время я предполагаю, что я простоне знаю, как получить форму из шаблона, многие примеры здесь создают форму по запросу, руководство, которому я следовал, создает форму в get_context_data, а затем передает ее шаблону.Поэтому я изо всех сил пытался выяснить, как сохранить или проверить правильность формы.
Извините за весь текст, но эти части настолько взаимосвязаны, что я хотел убедиться, что я включил все, что было бы полезно,Отображение и чтение из БД, кажется, работает, если я вручную захожу и добавляю голоса через административную панель, я могу их успешно прочитать, при попытке записать новый счет с помощью кнопки голосования ничего не происходит, ниже выводится окно терминала.
[12/Dec/2018 20:24:34] "GET /game/85 HTTP/1.1" 200 2081
[12/Dec/2018 20:46:49] "POST /game/85 HTTP/1.1" 302 0
[12/Dec/2018 20:46:49] "GET /game/vote/85/create HTTP/1.1" 302 0
[12/Dec/2018 20:46:49] "GET /game/85 HTTP/1.1" 200 2081
О, может быть, шаблоны URL-адресов могут быть полезны.
app_name = 'core'
urlpatterns = [
path('', views.MainPage.as_view(), name='MainPage'),
path('games', views.GameList.as_view(), name='GameList'),
path('game/<int:pk>', views.GameDetail.as_view(), name='GameDetail'),
path('game/vote/<int:game_id>/create', views.CreateVote.as_view(), name='CreateVote'),
path('game/vote/<int:game_id>/update/<int:pk>', views.UpdateVote.as_view(), name='UpdateVote'),
]
Заранее спасибо, я некоторое время бил головой об стену на этом.