post() takes exactly 1 argument (2 given) django - python

I've been coding this, so i wanted to create like a forum, and this is the comments part, if you guys can help me i will be really thankfull.
views.py
class createComment(View):
form_class = CommentForm
template_name = "createComment.html"
def get(self, request):
form = self.form_class(None)
return render(request, self.template_name, {'form':form})
def post(request):
try:
if request.method == "POST":
form = createComment()
if form.is_valid():
obj = form.save(commit=False)
obj.user_comment = request.user
obj.body_comment = request.POST["body_comment"]
obj.post_comment = request.POST[id]
obj.status_comment = False
obj.save()
return redirect('/')
else:
form = createComment()
except Exception, e:
return render_to_response("errorTemplate.html", {"message" : e.message})
return redirect('/')
models.py
class Comment(models.Model):
user_comment = models.ForeignKey("auth.User")
body_comment = models.TextField()
timestamp_comment = models.DateTimeField(auto_now=True)
post_comment = models.ForeignKey("Post", null=True)
status_comment = models.BooleanField()
def __unicode__(self):
return unicode(self.user_comment)
def __str__(self):
return self.title_comment

def get(self, request):
...
def post(request):
...
You forgot the self argument.

Related

How would I pass request.user into my form?

I'm trying to create a posts form that lets the user create posts on my site. I've been stuck on how to pass request.user into the fields "author" and "participants". Could anybody help?
Here is my view:
def home(request):
if request.method == "POST":
form = PostForm(request.POST)
if form.is_valid():
form.save()
return redirect('')
My model:
class Post(models.Model):
author = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
body = models.TextField()
category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True)
participants = models.ManyToManyField(User, related_name="participants", blank=True)
created = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ["-created"]
def __str__(self):
return self.body
And my form:
from django.forms import ModelForm
from .models import Post
class PostForm(ModelForm):
class Meta:
model = Post
fields = '__all__'
For the author you can use this.
def home(request):
if request.method == "POST":
form = PostForm(request.POST)
form.author = request.user
if form.is_valid():
form.save()
return redirect('')
For the participants you can wait until the new Post is created an then add the User
if form.is_valid():
new_post = form.save()
new_post.participants.add(user)
I have an example with class based views where is easy to accomplish.
class PostCreateView(CreateView):
template_name = 'Post/article_create.html'
form_class = ArticleModelForm
queryset = Article.objects.all()
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['form_journal'] = JournalModelForm
return context
def dispatch(self, request, *args, **kwargs):
if request.method == 'POST':
want_redirect = request.POST.get('want_redirect')
if not want_redirect:
self.success_url = reverse_lazy('article:article-create')
return super(ArticleCreateView, self).dispatch(request, *args, **kwargs)
def form_valid(self, form):
form.instance.user = self.request.user //I think this is what you are trying to do
return super().form_valid(form)

How to update an item in django without creating a new item?

I'm trying to update an item(book) present in the database, Even though I've added instance so that a new item is not created but instead the item is only updated, but unfortunately it's not working as it is supposed to, Instead of updating the item, a new item is being created, am I missing something in here?
models.py
class Book(models.Model):
book_name = models.CharField(max_length= 100)
author_name = models.CharField(max_length=100)
publisher = models.CharField(max_length=100)
published_on = models.DateTimeField(blank=True, null=True)
Language = models.CharField(max_length=100)
image = models.ImageField(blank = True, upload_to='images/')
created = models.DateTimeField(auto_now_add = True)
def __str__(self):
return self.book_name
#property
def imageURL(self):
try:
url = self.image.url
except:
url = " "
return url
views.py
def book_register(request):
if request.method == 'POST':
form = BookForm(request.POST, request.FILES)
if form.is_valid():
form.save()
return redirect('/')
else :
return render(request, 'crud_operation/book_form.html', {'form': form})
else:
form = BookForm()
context = {'form':form}
return render(request,'crud_operation/book_form.html',context)
def book_update(request,pk):
book = Book.objects.get(id=pk)
form = BookForm(instance = book)
if request.method == 'POST':
form = BookForm(request.POST, request.FILES, instance=book)
if form.is_valid():
form.save()
return redirect('/')
context = {'form':form}
return render(request, 'crud_operation/book_form.html',context)
urls.py
urlpatterns = [
path('create-book/',views.book_register, name = 'books'),
path('update-book/<int:pk>/',views.book_update, name = 'book_update'),
]
forms.py
class BookForm(ModelForm):
class Meta:
model = Book
fields = '__all__'
widgets = {
'published_on': DateInput(attrs={'type': 'date'})
}

Create #login_required like function for used Form(Modelform). So that User can't access confidential url without login-by typing just url?

I know that I can use #login_required but it is only used when we store user in User But in my case I stored model in form So it is not working for me. Also my created user is not getting authenticated when I use user.is_authenticated So I need custom login_required decorator which can be use to stop anyone from accessing direct url (confidential URl which are only accessed when you Login).
forms.py
class usrForm(forms.ModelForm):
password = forms.CharField(initial=123)
class Meta:
model = Person
fields = ('first_name','last_name','username','email','password','position')
def __init__(self, *args, **kwargs):
super(usrForm,self).__init__(*args,**kwargs)
self.fields['position'].empty_label = "Select"
class usrChange(forms.ModelForm):
class Meta:
model = Person
fields = ('username','password')
widgets= {
'password' : forms.PasswordInput(),
}
class loginForm(forms.ModelForm):
class Meta:
model = Person
fields = ('username','password')
widgets= {
'password' : forms.PasswordInput(),
}
models.py
class Position(models.Model):
title = models.CharField(max_length=50)
def __str__(self):
return self.title
class Person(models.Model):
first_name = models.CharField(max_length=50,default='')
last_name = models.CharField(max_length=50,default='')
username = models.CharField(max_length=50,default='')
password = models.CharField(max_length=50,default='')
email = models.EmailField(max_length=50)
position = models.ForeignKey(Position, on_delete=models.CASCADE)
def __str__(self):
return self.username
views.py
def user_list(request):
context = {'user_list' : Person.objects.all()}
return render(request, "usr_list.html", context)
def user_chnged_list(request):
form = usrForm(request.POST)
if form.is_valid():
form.save()
context = {'user_list' : Person.objects.all()}
return render(request, "usr_list.html", context)
def user_form(request, id=0):
if request.method == "GET":
if id ==0:
form = usrForm(initial={'password': 123}) # register
else:
auser = Person.objects.get(pk=id)
form = usrForm(instance=auser) #update
return render(request, "usr_form.html",{'form': form})
else:
if id == 0:
form = usrForm(request.POST , initial={'password': 123}) # register
else:
auser = Person.objects.get(pk=id) #update
form = usrForm(request.POST,instance=auser)
if form.is_valid():
form.save()
return redirect('login')
def user_delete(request,id):
auser = Person.objects.get(pk=id)
auser.delete()
return redirect('list')
def user_login(request):
form = loginForm()
if request.method == 'POST':
form = loginForm(data=request.POST)
if form.is_valid():
username=form.cleaned_data.get('username')
password=form.cleaned_data.get('password')
i = Person.objects.filter(username=username,password=password).exists()
user = {'user_list' : Person.objects.filter(username=username,password=password)}
if i == True:
j = Person.objects.filter(username=username, position_id = 1).exists()
if j == True:
return redirect('list')
return render(request,"usr_wlc.html", user )
else:
messages.error(request, 'Invalid username or password!')
context = {'form':form}
return render(request,'usr_login.html',context)
def user_detail(request,id):
auser = Person.objects.get(pk=id)
form = usrChange(request.POST,instance=auser)
if form.is_valid():
form.save()
return redirect('login')
def user_logout(request):
return redirect('/')
def user_change(request,id):
auser = Person.objects.get(pk=id) #update
form = usrChange(request.POST,instance=auser)
return render(request, "usr_chnge.html",{'form': form})

Django form.save(commit=False) not adding user_id

I am trying to add created by whoever is logged in user but not getting that saved even though I am logged in. form.created_by = request.user is not adding logged in user.
def create_table_allotment(request):
form = TableAllotmentForm(request.POST or None)
context = {'form': form}
if request.method == 'POST':
if form.is_valid():
try:
form.save(commit=False)
form.created_by = request.user
form.save()
return redirect('order_management:table_allotment_home')
except IntegrityError as err:
print('err => ', err)
context['unique_error'] = 'User has already assigned table for today'
return render(request, 'orders/table_allotment/create.html', context)
Here are my models
class QOTs(models.Model):
name = models.CharField(max_length=50)
alias = models.CharField(max_length=10)
def __str__(self):
return str(self.name)
class Meta:
verbose_name_plural = "QOTs"
class TableAllotment(models.Model):
employee = models.ForeignKey(User, on_delete=models.PROTECT)
qot = models.ForeignKey(QOTs, on_delete=models.PROTECT)
club = models.CharField(max_length=20, default='POS-0001')
from_table = models.IntegerField()
to_table = models.IntegerField()
working_date = models.DateField(default=timezone.now)
created_by = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True, related_name='qot_creator')
created_at = models.DateTimeField(_("Created at"), auto_now_add=True, editable=False)
updated_at = models.DateTimeField(_("Updated at"), auto_now=True)
class Meta:
ordering = ('-id',)
unique_together = ('employee', 'working_date',)
Here is my form
class TableAllotmentForm(forms.ModelForm):
class Meta:
model = models.TableAllotment
fields = ["employee", "qot", "from_table", "to_table"]
Please help
form.save(commit=False) will return the instance wrapped by the form which you can then modify and call save on. Instead you are just calling save on the form again and also you are setting form.created_by = request.user i.e. you are setting an attribute on the form.
Instead you should directly modify the instance wrapped by the form:
def create_table_allotment(request):
form = TableAllotmentForm(request.POST or None)
context = {'form': form}
if request.method == 'POST':
if form.is_valid():
try:
form.instance.created_by = request.user
form.save()
return redirect('order_management:table_allotment_home')
except IntegrityError as err:
print('err => ', err)
context['unique_error'] = 'User has already assigned table for today'
return render(request, 'orders/table_allotment/create.html', context)
Note: TableAllotmentForm(request.POST or None) is an anti-pattern (It is possible for an empty form to be valid in certain conditions) and you should simply pass request.POST only if
request.method == "POST" else you should simply write
TableAllotmentForm().
An alternative approach to what Abdul Aziz Barkat has suggested would be to assign returned object of save()(Django-Docs) method like so obj = form.save(commit=False).
I would also add #login_required to the view
from django.contrib.auth.decorators import login_required
#login_required
def create_table_allotment(request):
if request.method == 'POST':
form = TableAllotmentForm(request.POST)
if form.is_valid():
try:
obj = form.save(commit=False)
obj.created_by = request.user
obj.save()
return redirect('order_management:table_allotment_home')
except IntegrityError as err:
print('err => ', err)
context['unique_error'] = 'User has already assigned table for today'
else:
form = TableAllotmentForm()
context = {'form': form}
return render(request, 'orders/table_allotment/create.html', context)

Django try exception in class view

im only student so please bear with me. I already posted another topic about this but in function view. now i want to how do i convert this try exception to a class view and also add that comment form.
here's my views.py def
def BookDetail(request, id):
most_recent = Book.objects.order_by('-timestamp')[:3]
book= get_object_or_404(Book, id=id)
form = CommentForm(request.POST or None)
if request.method == "POST":
if form.is_valid():
form.instance.user = request.user
form.instance.post = book
form.save()
return redirect(reverse("book-detail", kwargs={
'id': book.pk
}))
if request.user.is_anonymous:
user_membership = None
else:
try:
user_membership = Customer.objects.get(user=request.user)
except Customer.DoesNotExist:
user_membership = None
context = {
'user_membership': user_membership,
'form': form,
'book': book,
'most_recent': most_recent,
}
return render(request, 'catalog/book_detail.html', context)
here is my new class view
class BookDetailView(NeverCacheMixin, generic.DetailView):
model = Book
UPDATE POST
here's my models.py..
class Book(models.Model):
slug = models.SlugField(unique=True, help_text="Enter BIC Code", null=True)
title = models.CharField(max_length=200) #more fields after this
timestamp = models.DateTimeField(default=timezone.now)
activeReference = models.ManyToManyField(Membership)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('book-detail', kwargs={'slug': self.slug})
#property
def get_comments(self):
return self.comments.all().order_by('-timestamp')
#property
def pages(self):
return self.page_set.all()
class Page(models.Model):
slug = models.SlugField(max_length=50)
book = models.ForeignKey(Book, on_delete=models.SET_NULL, null=True)
preview = models.FileField(upload_to='book_content', validators=[pdf_file_extension], help_text="PDF File Only")
def __str__(self):
return self.slug
def get_absolute_url(self):
return reverse('page-detail',
kwargs={
'book_slug': self.book.slug,
'page_slug': self.slug
})
here's my URL pattern
urlpatterns = [
path('', views.index, name='index'),
path('books/', views.BookListView.as_view(), name='book-list'),
path('book-detail/<slug>', views.BookDetailView.as_view(), name='book-detail'),
path('book-detail/<book_slug>/<page_slug>', views.PageDetailView.as_view(), name='page-detail'),
path('search/', views.Search, name='search'),
]
and my book_detail.html
{% for content in book.pages %}
Read
{% endfor %}
{% else %}
CBV are good when you need inheritance or need to deal with different HTTP methods to have the same route. If that is not the case, a FBV is a better choice. That being said, for what you are trying to do, you should just a FormView that will handle everything about a post and forms.
Something like:
class BookViewSet(FormView):
form = CommentForm
template_name = 'catalog/book_detail.html'
def form_valid(self, form):
self.send_mail(form.cleaned_data)
return super(BookViewSet, self).form_valid(form)
If you are handling forms, you should be using CreateView or FormView not DetailView. Here is an implementation example, as you can see is a little complex for someone new to Django:
from django.views.generic import CreateView
class BookDetailView(NeverCacheMixin, CreateView):
form_class = CommentForm
template_name = 'catalog/book_detail.html'
def dispatch(self, request, *args, **kwargs):
book_slug = self.kwargs.get('slug') # url variables are stored in self.kwargs
self.book = get_object_or_404(Book, slug=book_slug) # attach book to your view
return super().dispatch(request, *args, **kwargs)
def get_context_data(self, **kwargs):
# context data passed to template
kwargs['book'] = self.book
kwargs['most_recent'] = Book.objects.order_by('-timestamp')[:3]
if request.user.is_anonymous:
user_membership = None
else:
try:
user_membership = Customer.objects.get(user=self.request.user)
except Customer.DoesNotExist:
user_membership = None
kwargs['user_membership'] = user_membership
return super().get_context_data(**kwargs)
def form_valid(self, form):
instance = form.save(commit=False)
instance.user = self.request.user
instance.post = self.book
instance.save()
return redirect(self.book.get_absolute_url())

Categories

Resources