Django form.is_valid () неудачные представления на основе классов - Form, SingleObject, DetailMixins - PullRequest
0 голосов
/ 05 января 2020

У меня есть два приложения, здесь мы будем называть их блогом и комментариями.

Комментарии имеют модель комментариев. Блог имеет блог Модель. Комментарии имеют комментарий. Блог имеет DetailView.

Я хочу, чтобы моя CommentForm отображалась в Blog DetailView, чтобы люди могли отправлять комментарии со страницы сведений о блоге.

Форма отображает ОК - она ​​выполняет запрос POST, она перенаправляет на get_success_url (), но (я добавила несколько отпечатков в views.py - см. Ниже) при тестировании в views.py, чтобы увидеть, данные формы получены. Я вижу, что путь form.is_valid () не найден, и я не понимаю, почему.

По сути, я пытаюсь следовать этому, «лучшему альтернативному решению»: https://docs.djangoproject.com/en/2.2/topics/class-based-views/mixins/#using -formmixin-with-detailview

blog / views. py

class CommentLooker(SingleObjectMixin, FormView):
    template_name = 'blogs/blog_detail.html'
    form_class = CommentForm
    model = blog

    def get_object(self):
        #self.team = get_object_or_404(team, team_id=self.kwargs['team_id'])
        #queryset_list = blog.objects.filter(team = self.team)
        team_id_ = self.kwargs.get("team_id")
        blog_id_ = self.kwargs.get("blog_id")
        return get_object_or_404(blog, blog_id=blog_id_, team=team_id_)

    def post(self, request, *args, **kwargs):
        if not request.user.is_authenticated:
            return HttpResponseForbidden()
        self.object = self.get_object()
        return super(CommentLooker, self).post(request, *args, **kwargs)

    def get_success_url(self):
        return reverse('blogs:teams')

class blogDisplay(View):
    def get(self,request,*args,**kwargs):
        view = blogFromteamContentView.as_view()
        return view(request, *args, **kwargs)
    def post(self,request,*args,**kwargs):
        view = CommentLooker.as_view()
        return view(request,*args,**kwargs)

class blogFromteamContentView(LoginRequiredMixin, DetailView):
    model = blog
    template_name = 'blogs/blog_detail.html'
    # override get_object so we can use blog_id when we use this class in urls.py
    # otherwise DetailViews expect 'pk' which defaults to the primary key of the model.

    def get_object(self):
        team_id_ = self.kwargs.get("team_id")
        blog_id_ = self.kwargs.get("blog_id")
        return get_object_or_404(blog, blog_id=blog_id_, team=team_id_)

    def get_context_data(self, **kwargs):
        context = super(blogFromteamContentView, self).get_context_data(**kwargs)
        team_id_ = self.kwargs.get("team_id")
        blog_id_ = self.kwargs.get("blog_id")

        # get the list of blogs for a given blog id and team id combination.
        context['queryset'] = get_object_or_404(blog, blog_id=blog_id_, team=team_id_)

        # get and set things related to ability to associate comments to a blog.
        initial_data = {
                "content_type": blog.get_content_type,
                "object_id": blog.blog_id
            }
        comments        = blog.comments # uses the @property set in this class.
        comment_form    = CommentForm(self.request.POST or None, initial=initial_data)
        if comment_form.is_valid():
            print(comment_form.cleaned_data)
        else:
            print('invalido!')
        context['comment_form'] = comment_form
        return context

blog / models.py

class Blog(models.Model):
    team= models.ForeignKey(Team, on_delete=CASCADE)
    blog_id = models.AutoField(primary_key=True)
    blog_name = models.CharField(
        max_length=100, verbose_name='Blog Name')

blog / urls.py

path('teams/<int:team_id>/blogs/<int:blog_id>/', blog.blogDisplay.as_view(), name='detail'),

blog_detail. html

<div> 
<p class="lead"> Comments </p>
<form method="POST" action="."> {% csrf_token %}
    {{ comment_form}} 
    <input type="submit" value="Post Comment" class="btn btn-primary">
</form>
<hr/>
{% for comment in blog.comments.all %}

<blockquote class="blockquote">
    <p>{{ comment.content }}</p>
    <footer class="blockquote-footer"> {{ comment.user }} | {{ comment.timestamp|timesince }} ago </footer>
</blockquote>

<hr/>
{% endfor %}

comments / forms.py

из django формы импорта

class CommentForm(forms.Form):
    content_type = forms.CharField(widget=forms.HiddenInput)
    object_id = forms.IntegerField(widget=forms.HiddenInput)
    parent_id = forms.IntegerField(widget=forms.HiddenInput, required=False)
    content = forms.CharField(widget=forms.Textarea)

редактировать:

после использования print (comment_form.errors):

object_id Введите целое число.

предположить, что мои исходные_данные могут быть проблемой. Фактически, и content_type, и object_id в моих initial_data были проблемами. Я просил blog.blog_id - т. Е. Используя класс, а не экземпляр. Поэтому я изменил

get_context_data:

def get_context_data(self, **kwargs):
context = super(blogFromteamContentView, self).get_context_data(**kwargs)
team_id_ = self.kwargs.get("team_id")
blog_id_ = self.kwargs.get("blog_id")

# get the list of blogs for a given blog id and team id combination.
context['queryset_list_recs'] = get_object_or_404(blog, blog_id=blog_id_, team=team_id_)

instance = get_object_or_404(blog, blog_id=blog_id_, team=team_id_)
initial_data = {
        "content_type": instance.get_content_type,
        "object_id": blog_id_
    }

и на мои views.py:

def post(self, request, *args, **kwargs):
    if not request.user.is_authenticated:
        return HttpResponseForbidden()
    self.object = self.get_object()
    comment_form = CommentForm(self.request.POST)
    if comment_form.is_valid():
        print('valido')
        c_type = comment_form.cleaned_data.get("content_type")
        content_type = ContentType.objects.get(model=c_type)
        obj_id = comment_form.cleaned_data.get('object_id')
        content_data = comment_form.cleaned_data.get("content")
        new_comment, created = Comment.objects.get_or_create(
            user = self.request.user,
            content_type = content_type,
            object_id = obj_id,
            content = content_data
        )
    else:
        print('postinvalido!')
    return super(CommentLooker, self).post(request, *args, **kwargs)

This ( неуместные заявления о печати в стороне) теперь, кажется, дает предполагаемое поведение.

1 Ответ

0 голосов
/ 05 января 2020

после использования print (comment_form.errors):

  • object_id
  • Элемент списка

Введите целое число.

предположить, что мои исходные_данные могут быть проблемой. Фактически, и content_type, и object_id в моих initial_data были проблемами. Я просил blog.blog_id - т. Е. Используя класс, а не экземпляр. Поэтому я изменил

get_context_data:

def get_context_data(self, **kwargs):
context = super(blogFromteamContentView, self).get_context_data(**kwargs)
team_id_ = self.kwargs.get("team_id")
blog_id_ = self.kwargs.get("blog_id")

# get the list of blogs for a given blog id and team id combination.
context['queryset_list_recs'] = get_object_or_404(blog, blog_id=blog_id_, team=team_id_)

instance = get_object_or_404(blog, blog_id=blog_id_, team=team_id_)
initial_data = {
        "content_type": instance.get_content_type,
        "object_id": blog_id_
    }

и на мои views.py :

def post(self, request, *args, **kwargs):
    if not request.user.is_authenticated:
        return HttpResponseForbidden()
    self.object = self.get_object()
    comment_form = CommentForm(self.request.POST)
    if comment_form.is_valid():
        print('valido')
        c_type = comment_form.cleaned_data.get("content_type")
        content_type = ContentType.objects.get(model=c_type)
        obj_id = comment_form.cleaned_data.get('object_id')
        content_data = comment_form.cleaned_data.get("content")
        new_comment, created = Comment.objects.get_or_create(
            user = self.request.user,
            content_type = content_type,
            object_id = obj_id,
            content = content_data
        )
    else:
        print('postinvalido!')
    return super(CommentLooker, self).post(request, *args, **kwargs)

This ( неподходящие печатные заявления в стороне) теперь, кажется, дает предполагаемое поведение. Мне неясно, почему экземпляр метода CommentForm должен быть создан внутри метода post - мне кажется, что я здесь что-то не так делаю.

...