Sunday, April 28, 2019

Re: Question about form_valid: how to automatically set multiple fields when users input data via CreateView supported form?

Hi Chiraq,

Thank you for your reply.
Please find the attached screen shot as well.

I extended CreatView as CommentCreateView.
I don't have form.py. Just using built-in form.
I made a template for comment and used form.as_p.
This is article_comment_new.html.

{% extends 'base.html' %}

{% block content %}
<h1>New Comment</h1>
<form action="" method="post">{% csrf_token %}
  {{ form.as_p }}
  <button class="btn btn-success ml-2" type="submit">Save</button>
</form>
{% endblock content %}


Here is models.py
from django.conf import settings
from django.contrib.auth import get_user_model
from django.db import models
from django.urls import reverse

class Article(models.Model):
title = models.CharField(max_length=255)
body = models.TextField()
date = models.DateTimeField(auto_now_add=True)
author = models.ForeignKey(
get_user_model(),
on_delete=models.CASCADE,
)

def __str__(self):
return self.title

def get_absolute_url(self):
return reverse('article_detail', args=[str(self.id)])

class Comment(models.Model): # new
    article = models.ForeignKey(
    Article,
    on_delete=models.CASCADE,
    related_name = 'comments',
    )
    comment = models.CharField(max_length=140)
    author = models.ForeignKey(
        get_user_model(),
        on_delete=models.CASCADE,
    )

    def __str__(self):
        return self.comment

    def get_absolute_url(self):
        return reverse('article_list')


Here is views.py
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.mixins import UserPassesTestMixin
from django.views.generic import ListView
from django.views.generic import DetailView
from django.views.generic.edit import UpdateView
from django.views.generic.edit import DeleteView
from django.views.generic.edit import CreateView

from django.urls import reverse_lazy

from .models import Article
from .models import Comment


class ArticleListView(ListView):
model = Article
template_name = 'article_list.html'


class ArticleDetailView(DetailView):
model = Article
template_name = 'article_detail.html'


class ArticleUpdateView(LoginRequiredMixin, UserPassesTestMixin, UpdateView):
model = Article
fields = ('title', 'body',)
template_name = 'article_edit.html'
login_url = 'login'

def test_func(self):
obj = self.get_object()
return obj.author == self.request.user


class ArticleDeleteView(LoginRequiredMixin, UserPassesTestMixin, DeleteView):
model = Article
template_name = 'article_delete.html'
success_url = reverse_lazy('article_list')
login_url = 'login'

def test_func(self):
obj = self.get_object()
return obj.author == self.request.user

def superuser_required():
    def wrapper(wrapped):
        class WrappedClass(UserPassesTestMixin, wrapped):
            def test_func(self):
                return self.request.user.is_superuser

        return WrappedClass
    return wrapper

@superuser_required()
class ArticleCreateView(LoginRequiredMixin, CreateView):
model = Article
template_name = 'article_new.html'
fields = ('title', 'body',)
login_url = 'login'

def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)

#for comment
class ArticleCommentCreateView(LoginRequiredMixin, CreateView):
model = Comment
template_name = 'article_comment_new.html'
fields = ('comment',)
login_url = 'login'

def form_valid(self, form):
form.instance.author = self.request.user # this is working fine
print(form.instance.article)
# form.instance.article = self.request.POST.get('article'), doesn't work

print(dir(self.request.POST)) 
print(self.request.POST.items)
# print(self.request.user)
# print(self.request.POST.user), doesn't work
# form.instance.article = self.request.get('article'), doesn't work
# form.instance.article = request.POST.get('article'), doesn't work
# form.instance.article = self.instance.article, doesn't work
return super().form_valid(form)




On Sunday, April 28, 2019 at 3:05:53 AM UTC-4, chirag soni wrote:
Please share the form and form template as well. 

On Sun, 28 Apr 2019, 02:37 Atsunori Kaneshige <atsu...@umich.edu wrote:
I really appreciate if anybody could give me an advice about form_valid.

Here is what I want to do.
I am making a simple blog.
I am making simple features:
1) only superuser can create articles.
2) logged-in users can make comments to articles.

I followed along tutorials and mostly done.
But last thing I want to do is that when users make comments to any articles, I want author field and article field to be automatically set.
Currently, users need to choose author field and article field to make comments as well as comment texts.

The tutorial that I followed along uses form_valid and by using form_valid, now I don't need to choose author.
But I have been struggling with how to automatically set article field by using form_valid.

I have a simple models.py and views.py below.

<models.py>

class Article(models.Model):
title = models.CharField(max_length=255)
body = models.TextField()
date = models.DateTimeField(auto_now_add=True)
author = models.ForeignKey(
get_user_model(),
on_delete=models.CASCADE,
)

def __str__(self):
return self.title

def get_absolute_url(self):
return reverse('article_detail', args=[str(self.id)])

class Comment(models.Model): # new
    article = models.ForeignKey(
    Article,
    on_delete=models.CASCADE,
    related_name = 'comments',
    )
    comment = models.CharField(max_length=140)
    author = models.ForeignKey(
        get_user_model(),
        on_delete=models.CASCADE,
    )

    def __str__(self):
        return self.comment

    def get_absolute_url(self):
        return reverse('article_list')

<views.py>
...(not showing all)
#for comment
class ArticleCommentCreateView(LoginRequiredMixin, CreateView):
model = Comment
template_name = 'article_comment_new.html'
fields = ('comment',)
login_url = 'login'

def form_valid(self, form):
form.instance.author = self.request.user
form.instance.article = self.request.article
return super().form_valid(form)

I keep getting errors with this code.
I know that form.instance.article = self.request.article is something wrong, but I am having hard time to figure out how to set article field to be automatically set.


Please give any advice about this.
I really appreciate.

Looking forward to hearing from anyone.

Best regards,

Nori




--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django...@googlegroups.com.
To post to this group, send email to django...@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/fe3a8f1d-2e97-41f8-8af4-fe638cb9e787%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/ac505365-4749-43e9-b080-c09917231dcd%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

No comments:

Post a Comment