Django Invalid Form - django

I have a modal with a form in it. The issue is that on invalid form it does return the form errors but it also closes the modal dialog box by rendering the home page again. It is also the home page so the return render is needed for the logging in.
How would I just return to the screen if the post fails.
def index(request):
context = {}
if request.method == "POST":
print(request.POST)
form = UserProfileForm(request.POST or None, request.FILES or None,instance=request.user)
if form.is_valid():
form.save()
return redirect('home')
else:
form = UserProfileForm()
context['form']= form
return render(request, "home.html", context)
modal
{% block content %}
<div class="modal fade" id="editProfile" tabindex="-1" role="dialog" aria-labelledby="editProfilelCenterTitle" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="editProfileLongTtitle">Edit Profile</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
{% include 'form.html' %}
</div>
</div>
</div>
</div>
{% endblock %}
form.html
{% block content %}
<form method = "POST" action='.' enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Upload</button>
</form>
{% endblock %}
home.html
{% extends 'base.html' %}
{% block title %}Home{% endblock %}
{% block content %}
{% if user.is_authenticated %}
<div class="container">
{% include 'editProfileModal.html' %}
<div class='row'>
{% include 'sidebar.html' %}
</div>
</div>
{% else %}
<p>You are not logged in</p>
Log In
Sign up
{% endif %}
{% endblock %}

You need shows the modal while you're sending a POST request and the view don't send the redirect. You can try the next poor solution. It's ugly but can work:
def index(request):
context = {'is_post': False}
if request.method == "POST":
context['is_post'] = True
form = UserProfileForm(request.POST or None, request.FILES or None,instance=request.user)
if form.is_valid():
form.save()
return redirect('home')
else:
form = UserProfileForm()
context['form']= form
return render(request, "home.html", context)
{% block content %}
<div class="modal fade" id="editProfile" tabindex="-1" role="dialog" ... >
<!-- your content ... -->
</div>
<!-- Do this after jQuery loaded -->
{% if is_post %}
<script type="text/javascript">
$(window).on('load', function() {
$('#myModal').modal('show');
});
</script>
{% endif %}
{% endblock %}

You can simple return HttpResponse with form errors.
from django.http import HttpResponse
if form.is_valid():
...
else:
return HttpResponse(form.errors.as_json())

Try this:
def index(request):
context = {}
if request.method == "POST":
print(request.POST)
form = UserProfileForm(request.POST or None, request.FILES or None,instance=request.user)
if form.is_valid():
form.save()
return redirect('home')
context['form']= form
return render(request, "home.html", context)

Related

Save list of forms Django

i've managed how to display a list of determined forms, without using formsets. But now i'm strugling to save the data from the form.
This is my template:
{% extends 'base.html' %}
{% block main %}
<div class="container">
<div class="container-form">
<form method="POST" enctype="multipart/form-data" action="{% url 'adjust_values' contract.id %}">
{% csrf_token %}
{% for form in items_forms %}
{{ form }}
{% endfor %}
<button type="submit" class="btn-confirm">Confirm</button>
</form>
</div>
<div class="container-descript">
<h2 class="h2-containter">Adjust your prices!</h2>
<img src="https://i.ibb.co/pX0bq35/Illustration.png" class="img-form">
</div>
</div>
{% endblock %}
This is my views.py
#login_required
def adjust_values(request, id):
contract = get_object_or_404(ClientContract.objects.filter(user=request.user), pk=id)
contract_items = contract.items.all()
items_forms = []
for item in contract_items:
items_forms.append(
ItemForm(request.POST or None, instance=item)
)
my_forms = all([form.is_valid() for form in items_forms])
form = ItemForm()
if my_forms and form.is_valid():
for form in items_forms:
form.save(commit=False)
form.save()
else:
print(form.errors)
context = {'contract': contract, 'form':form, 'items_forms': items_forms}
return render(request, 'item_formset.html', context)
Now i really do not know what i need to do to save the data from the forms. Is there any way to save the data using this structure for iteration trough forms?

how to display a form in function based view

I have got an error when I tried to display a form in function-based view in Django. I could display it in another HTML file and users can make their comments to the blog. But, I think it can be more convenient for users if they can make a comment on the same blog-detail HTML file, so I wanna implement it.
When I tried, this error showed up. "NoReverseMatch at /blogs/blog/30/
Reverse for 'blog' with no arguments not found. 1 pattern(s) tried: ['blogs/blog/(?P[0-9]+)/$']"
Any comments can help me and thanks for your time in advance!!
Here are the codes I wrote...
from django import forms
from .models import Comment
class CommentForm(forms.ModelForm):
class Meta:
model = Comment
fields = ('user', 'text',)
#views.py
#login_required
def blog(request, pk):
blog = get_object_or_404(Blog, pk=pk)
form = CommentForm()
# if request.method == 'POST':
# form = CommentForm(request.POST)
# if form.is_valid():
# comment = form.save(commit=False)
# comment.blog = blog
# comment.save()
# return redirect('blog', pk=blog.pk)
# else:
# form = CommentForm()
if blog.link_1 is not None and blog.link_2 is not None:
link_1 = blog.link_1
link_2 = blog.link_2
context = {
'blog': blog,
'link_1': link_1,
'link_2': link_2,
'form': form,
}
elif blog.link_1 is not None or blog.link_2 is not None:
link_1 = blog.link_1
link_2 = blog.link_2
context = {
'blog': blog,
'link_1': link_1,
'link_2': link_2,
'form': form,
}
else:
context = {
'blog': blog,
'form': form,
}
return render(request, 'blog/blog.html', context)
#login_required
def add_comment(request, pk):
blog = get_object_or_404(Blog, pk=pk)
if request.method == 'POST':
form = CommentForm(request.POST)
if form.is_valid():
comment = form.save(commit=False)
comment.blog = blog
comment.save()
return redirect('blog', pk=blog.pk)
else:
form = CommentForm()
context = {
'form': form,
}
return render(request, 'blog/blog.html', context)
#urls.py
path('blog/<int:pk>/', views.blog, name='blog'),
path('blog/<int:pk>/comment/', views.add_comment, name='add_comment'),
#blog.html
{% extends 'base.html' %}
{% block title %}|{{ blog.title }}{% endblock %}
{% block content %}
<div class="header-bar">
← 戻る
</div>
<div class="body-container">
<div class="created-edit-delete">
<p>
{% if request.user == blog.user %}
あなたが{{ blog.created }}に作成</p>
{% else %}
{{ blog.user }}が{{ blog.created }}に作成</p>
{% endif %}
<div class="icons">
{% if request.user == blog.user %}
{% endif %}
</div>
</div>
<h1>{{ blog.title }}</h1>
<p class="blog-content">{{ blog.content_1 }}</p>
{% if blog.content_2 %}
<p class="blog-content">{{ blog.content_2 }}</p>
{% endif %}
{% if blog.content_2 %}
<p class="blog-content">{{ blog.content_3 }}</p>
{% endif %}
<div class="ref-links">
{% if link_1 %}
参考リンク
{% endif %}
{% if link_2 %}
参考リンク
{% endif %}
</div>
<hr>
<div class="comment-area">
<div class="comment-form">
<h2>New comment</h2>
<form action="{% url 'add_comment' blog.id %}" method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="button">追加</button>
</form>
</div>
<div class="comment-all">
{% for comment in blog.comments.all %}
<div class="comment">
<div class="date">{{ comment.created }}</div>
<strong>{{ comment.user }}</strong>
<p>{{ comment.text|linebreaks }}</p>
</div>
{% empty %}
<p>No comments here yet :(</p>
{% endfor %}
</div>
</div>
</div>
{% endblock %}
You have called blog URL here ← 戻る and forgot to pass id inside your URL that's why it's showing this error
NoReverseMatch at /blogs/blog/30/ Reverse for 'blog' with no arguments not found. 1 pattern(s) tried: ['blogs/blog/(?P[0-9]+)/$']
you have to pass id here like this
← 戻る

PasswordChangeForm with Abstractuser not responsive on submit

I have a custom user model
class User(AbstractUser):
company = models.CharField(max_length=30, blank=True)
When I try to change my password using the ChangePasswordForm, upon submit, nothing happens.
#login_required
def change_password(request):
if request.method == 'POST':
form = PasswordChangeForm(data=request.POST, user=request.user)
if form.is_valid():
form.save()
update_session_auth_hash(request, form.user)
return redirect('/account/profile')
else:
form = PasswordChangeForm(request.user)
args = {'form': form}
return render(request, 'accounts/change_password.html', args)
change_password.html
{% extends 'base.html' %}
{% block head %}
{% endblock %}
{% load crispy_forms_tags %}
{% crispy form form.helper %}
{% block body %}
<div class="container-fluid">
<div class="card">
<div class="card-body">
<h3>Change password</h3><br>
<form method="post">
{% csrf_token %}
{% crispy form %}
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
</div>
</div>
{%endblock%}
This was working before with a regular usermodel
hope someone can help.

Twitter-Bootstrap modal and django form

I'd like to show last_item in a Twitter-Bootstrap modal after django form submission, however I don't know how to handle the modal. I tried the form button suggested in documentation, but it doesn't process the form data. What do I have to do?
<button data-toggle="modal" data-target="#myModal2">Submit</button>
views.py
def main(request):
if request.method == 'POST':
form = MyModelForm(request.POST)
if form.is_valid():
name = form.cleaned_data['name']
request.session['name'] = name
mm = MyModel.objects.create(name=name)
mm.save()
return HttpResponseRedirect('/') # Redirect after POST
else:
form = MyModelForm()
args = {}
args['last_item'] = MyModel.objects.all().order_by('pk').reverse()[0]
args['form'] = form
return render(request, 'form.html', args)
form.html
{% extends "base.html" %}
{% block content %}
<form method="POST" id="" action="">
{% csrf_token %}
{{ form.as_p }}
<button>Submit</button>
</form>
<div class="modal" id="myModal2" tabindex="-1" role="dialog"
aria-labelledby="myModal2Label" aria-hidden="true" style="display: none">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3 id="myModal2Label">Modal header</h3>
</div>
<div class="modal-body">
<p>Last item: {{ last_item }}</p>
</div>
</div>
{% endblock %}
{% block scripts %}
{% endblock %}
It seems like bootstrap calls event.preventDefault() on click, which prevents the form from being submited.
You should bind your own event on this button and close the modal programaticaly.
It could look like:
$('form').submit(function() {
$('#myModal2').modal('hide');
})
I did not test this code but it should be a good start.

Simple Django form in Twitter-Bootstrap modal

I'm trying to run django forms with Twitter-Bootstrap modals. I'd like to know what should I do to return to / after form submission. My views and templates are below.
url.py
urlpatterns = patterns('myapp.views',
url(r'^$', 'main'),
url(r'^add/', 'form_add'),
)
views.py
def main(request):
if request.method == 'POST':
form = MyModelForm(request.POST)
if form.is_valid():
name = form.cleaned_data['name']
request.session['name'] = name
mm = MyModel.objects.create(name=name)
mm.save()
return HttpResponseRedirect('/add') # Redirect after POST
else:
form = MyModelForm()
args = {}
args['last_item'] = MyModel.objects.all().order_by('pk').reverse()[0]
args['form'] = form
return render(request, 'form.html', args)
def form_add(request):
args = {}
name = request.session['name']
return render(request, 'add.html', args)
form.html
{% extends "base.html" %}
{% block content %}
<button type="button" data-toggle="modal"
data-target="#myModal1">Launch modal</button>
<div class="modal" id="myModal1" tabindex="-1" role="dialog"
aria-labelledby="myModal1Label" aria-hidden="true" style="display: none">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3 id="myModal1Label">Modal header</h3>
</div>
<div class="modal-body">
<form method="POST" id="" action="">
{% csrf_token %}
{{ form.as_p }}
<button>Submit</button>
</form>
</div>
</div>
<p>Last item: {{ last_item }}</p>
{% endblock %}
{% block scripts %}
{% endblock %}
Comment converted to answer.
HttpResponseRedirect('/') instead of '/add'?