Отправка данных из представления Django в форму Django

У меня есть представление Django, и я хочу отправить данные запроса на форму.

class PostDetailView(DetailView):

    model = Post
    form = CommentForm

    def get_form_kwargs(self):
        kwargs = super(PostDetailView, self).get_form_kwargs()
        kwargs['user'] = self.request.user.username
        return kwargs

    def post(self, request, *args, **kwargs):
        form = CommentForm(request.POST)
        if form.is_valid():
            post = self.get_object()
            form.instance.user = request.user
            form.instance.post = post
            form.save()
            return redirect(reverse("post-detail", args=[post.pk]))



from django import forms
from .models import Comment
from djrichtextfield.widgets import RichTextWidget

class CommentForm(forms.ModelForm):

    user = forms.ChoiceField(required=True)

    def __init__(self, *args, **kwargs):
        self.user = kwargs.pop('user', None)
        super(CommentForm, self).__init__(*args, **kwargs)
        self.fields['user'].choices = self.user

    content = forms.CharField(widget=RichTextWidget(attrs={
        'class': 'md-textarea form-control',
        'placeholder': 'Comment here ...',
        'rows': '4',
    }))

    class Meta:
        model = Comment
        fields = ('author', 'content',)

Согласно документации, get_form_kwargs позволяет задавать пары ключ-значение в kwargs. Затем эти kwargs передаются в форму. Функция формы init должна быть способна подхватить значение пользователя из kwargs.

Однако, self.user возвращает None, и отладка показала, что get_form_kwargs вообще не выполняется.

У меня два вопроса: как выполняются функции в классах представления? И какой правильный метод передачи данных из представления в форму?

В документации это явно не описано, но get_form_kwargs срабатывает только при наличии CreateView или UpdateView.

В вашем случае вы можете использовать UpdateView, а затем использовать form_valid для выполнения пост-процесса. Но обратите внимание, что нам нужно удалить kwargs['instance'], потому что по умолчанию это представление будет думать, что мы работаем с объектом Post, когда на самом деле это Comment:

Попробуйте с этим:

class PostDetailView(UpdateView):
    model = Post
    form = CommentForm

    def get_form_kwargs(self):
        kwargs = super(PostDetailView, self).get_form_kwargs()
        # Remove the post object as instance, 
        # since we are working with a comment
        kwargs.pop('instance', None)
        kwargs['user'] = self.request.user.username
        return kwargs

    def form_valid(self, form):
        instance = form.save(commit=False)
        instance.user = self.request.user
        instance.post = self.get_object() # returns the post
        instance.save()
        return redirect(reverse("post-detail", args=[post.pk]))

или, если вы не хотите использовать UpdateView (не рекомендуется), вы можете просто явно вызвать get_form_kwargs при построении формы. Однако вы не можете вызвать super().get_form_kwargs(), поскольку, как уже говорилось, родительский класс не имеет этого метода:

class PostDetailView(DetailView):
    model = Post
    form = CommentForm

    def get_form_kwargs(self):
        kwargs = {'user': self.request.user.username}
        return kwargs

    def post(self, request, *args, **kwargs):
        form = CommentForm(request.POST, **self.get_form_kwargs())
        if form.is_valid():
            post = self.get_object()
            form.instance.user = request.user
            form.instance.post = post
            form.save()
            return redirect(reverse("post-detail", args=[post.pk]))

И последнее, подумайте о переименовании этого класса, поскольку мы работаем с добавлением комментария к посту, а не с "деталями поста", поэтому что-то вроде PostAddCommentView?

Вернуться на верх