Tengo este mapeo de URL:
url(r'^article/(?P<slug>[-\w]+)/$', views.ArticleView.as_view(), name='article-detail'),y tengo esta vista:
class ArticleView(DetailView): model = Article template_name = 'template/article.html' context_object_name = 'article' def get_context_data(self, **kwargs): context = super(ArticleView, self).get_context_data(**kwargs) context['comments'] = self.object.comment_set.filter(approved=True) return context Ya he mostrado todos los comentarios aprobados (como puede ver), pero no sé cómo crear un formulario de comentarios dentro de ArticleView. Tengo este ModelForm :
class CommentForm(forms.ModelForm): class Meta: model = Comment fields = '__all__'y... Modelo de comentario:
class Comment(models.Model): author = models.CharField(max_length=100) article = models.ForeignKey(Article, on_delete=models.CASCADE) email = models.EmailField() message = models.TextField(max_length=1000) created_at = models.DateTimeField(auto_now_add=True) approved = models.BooleanField(default=False)El problema con CommentForm es que no sé cómo 'ocultar' el artículo y los campos aprobados y cómo llenar el campo del artículo con el artículo obtenido en ArticleView.
Intenté combinar FormMixin con DetailView pero... cuando envío el formulario de comentarios, la consola muestra: Method not Allowed (POST) . ¿Cómo puedo crear una vista de formulario en ArticleView?
Si no entendiste algo, por favor pregúntame, sé que mi gramática es mala. Intentaré ser lo más claro posible.
Gracias por adelantado por las respuestas.
Lo resolví, algo así..
class ArticleView(FormMixin, DetailView): model = Article template_name = 'template/article.html' form_class = CommentForm def get_success_url(self): return reverse('article-detail', kwargs={'slug': self.object.slug}) def get_context_data(self, **kwargs): context = super(ArticleView, self).get_context_data(**kwargs) context['form'] = CommentForm(initial={ 'article': self.object }) context['comments'] = self.object.comment_set.filter(approved=True) return context def post(self, request, *args, **kwargs): self.object = self.get_object() form = self.get_form() if form.is_valid(): return self.form_valid(form) else: return self.form_invalid(form) def form_valid(self, form): form.save() return super(ArticleView, self).form_valid(form) en forms.py :
class CommentForm(forms.ModelForm): class Meta: model = Comment exclude = ('admitted',) widgets = { 'article': forms.HiddenInput() }La única forma en que podía... establecer un valor para ese campo de artículo (que es una clave externa para el artículo) era establecer el valor inicial en ArticleView.
Si alguien tiene una mejor alternativa, también me alegro de verla.
Establecer una variable temporal como esta y no tendrá que establecer un valor inicial en ArticleView
Simplemente como esto
context['form'] = self.get_form()y esto
def form_valid(self, form): new_comment = form.save(commit=False) new_comment.post = self.get_object() return super(ArticleView, self).form_valid(form)Sé que han pasado años, pero tal vez mi respuesta sea útil para alguien. La respuesta de Yierstem funcionó para mí, pero hice algunos cambios.
Primero, cambió get_success_url para usar get_absolute_url del modelo principal:
def get_success_url(self): return self.object.get_absolute_url() Agregue primero el método get_absolute_url al modelo principal:
def get_absolute_url(self): return reverse('record_detail', args=[str(self.pk)] En segundo lugar, agrego mi artículo objetivo y autor (ForeignKey(s) de mi modelo de comentarios) dentro del método form_valid :
def form_valid(self, form): new_comment = form.save(commit=False) new_comment.target = self.object new_comment.author = self.request.user new_comment.save() return super(RecordDetailView, self).form_valid(form)