Form not resetting upon submission? - python

I have a page with a form that once it gets submitted, the form loads again for the next person. I switched from class based views to function based due to a problem I was having to render modals and I noticed that now, since I'm not redirecting to the form again, it does not clear the data that was entered previously. How can I clear the form upon submission?
views.py
def enter_exit_area(request):
form = WarehouseForm(request.POST or None)
enter_without_exit = None
exit_without_enter = None
if form.is_valid():
emp_num = form.cleaned_data['employee_number']
area = form.cleaned_data['work_area']
station = form.cleaned_data['station_number']
if 'enter_area' in request.POST:
# Some rules to open modals/submit
message = 'You have entered %(area)s' % {'area': area}
if station is not None:
message += ': %(station)s' % {'station': station}
messages.success(request, message)
elif 'leave_area' in request.POST:
# more Rules
message = 'You have exited %(area)s' % {'area': area}
if station is not None:
message += ': %(station)s' % {'station': station}
messages.success(request, message)
return render(request, "operations/enter_exit_area.html", {
'form': form,
'enter_without_exit': enter_without_exit,
'exit_without_enter': exit_without_enter,
})
forms.py
class WarehouseForm(AppsModelForm):
class Meta:
model = EmployeeWorkAreaLog
widgets = {
'employee_number': ForeignKeyRawIdWidget(EmployeeWorkAreaLog._meta.get_field('employee_number').remote_field, site, attrs={'id':'employee_number_field'}),
}
fields = ('employee_number', 'work_area', 'station_number', 'edited_timestamp')
enter_exit_area.html
{% extends "base.html" %}
{% load core_tags %}
{% block main %}
{% if enter_without_exit %}
<div id="auto-open-ajax-modal" data-modal="#create-update-modal" data-modal-url="{% url "operations:update_timestamp_modal" enter_without_exit.id %}" class="hidden"></div>
{% endif %}
{% if exit_without_enter %}
<div id="auto-open-ajax-modal" data-modal="#create-update-modal" data-modal-url="{% url "operations:update_timestamp_modal" exit_without_enter.id %}" class="hidden"></div>
{% endif %}
<form id="warehouseForm" action="" method="POST" class="form-horizontal" novalidate >
{% csrf_token %}
<div>
<div>
<label>Employee</label>
{{ form.employee_number }}
</div>
<div>
<label>Work Area</label>
{{ form.work_area }}
</div>
<label>Station</label>
{{ form.station_number }}
</div>
</div>
<div>
<div>
<button type="submit" name="enter_area" value="Enter">Enter Area</button>
<button type="submit" name="leave_area" value="Leave">Leave Area</button>
</div>
</div>
</form>
{% modal id="create-update-modal" title="Update Timestamp" primary_btn="Submit" default_submit=True %}
{% endblock main %}

# Form not resetting upon submission, because you are sending data to your form
form = WarehouseForm(request.POST or None)
# If you want to reset your form, you should not send data to your form
form = WarehouseForm()
For Example:-
if request.method == 'POST':
form = WarehouseForm(request.POST or None)
else:
form = WarehouseForm()
# Your views.py can be:-
views.py
def enter_exit_area(request):
enter_without_exit = None
exit_without_enter = None
if request.method == 'POST':
form = WarehouseForm(request.POST or None)
if form.is_valid():
emp_num = form.cleaned_data['employee_number']
area = form.cleaned_data['work_area']
station = form.cleaned_data['station_number']
if 'enter_area' in request.POST:
# Some rules to open modals/submit
message = 'You have entered %(area)s' % {'area': area}
if station is not None:
message += ': %(station)s' % {'station': station}
messages.success(request, message)
elif 'leave_area' in request.POST:
# more Rules
message = 'You have exited %(area)s' % {'area': area}
if station is not None:
message += ': %(station)s' % {'station': station}
messages.success(request, message)
else:
form = WarehouseForm()
return render(request, "operations/enter_exit_area.html", {
'form': form,
'enter_without_exit': enter_without_exit,
'exit_without_enter': exit_without_enter,
})

Related

Django "if request.method == 'POST':" returns False

I'm making Django app and I have an issue, I've never had problem with before. As always in form view, I'm checking if request.method == 'POST' but somehow it returns False,
My code looks like that:
def recipe_create_view(request):
context = {}
form = RecipeForm(request.POST or None)
IngredientFormset = formset_factory(IngredientForm)
formset = IngredientFormset(request.POST or None)
context['form'] = form
context['formset'] = formset
if request.method == 'POST':
if form.is_valid():
if formset.is_valid():
form.save()
print("made a recipe")
for form in formset:
child = form.save(commit=False)
child.recipe = parent
child.save()
print("made a Ingredient")
else:
print("formset is not valid")
else:
print("form is not valid")
else:
print("request method is not correct")
return render(request, 'recipes/create_recipe.html', context)
create_recipe.html file:
<form method="POST">
{% csrf_token %}
<label>recipe</label>
<p>{{form}}</p>
<label>ingredients</label>
{% for form in formset %}
<ul>
<label>name</label>
<li>{{ form.name }}</li>
<label>quantity</label>
<li>{{ form.quantity }}</li>
</ul>
{% endfor %}
<div>
<input type="submit" value="submit" class="button-33" role="button">
</div>
</form>
Where is the problem?
It is necessary to return HttpResponseRedirect after dealing with POST data, the tip is not specific to Django, it's a good web practice in general.
Also, try to maintain both GET and POST request separately, so try below view:
def recipe_create_view(request):
context = {}
form="" # for the error of variable refrenced before assignment.
IngredientFormset=""
formset=""
if request.method == 'POST':
form = RecipeForm(request.POST)
IngredientFormset = formset_factory(IngredientForm)
formset = IngredientFormset(request.POST)
if form.is_valid():
if formset.is_valid():
form.save()
print("made a recipe")
for form in formset:
child = form.save(commit=False)
child.recipe = parent
child.save()
print("made a Ingredient")
return redirect('some_success_path_name')
else:
print("formset is not valid")
else:
print("form is not valid")
else: # GET method
print("request method is GET")
form = RecipeForm()
IngredientFormset = formset_factory(IngredientForm)
formset = IngredientFormset()
context['form'] = form
context['formset'] = formset
return render(request, 'recipes/create_recipe.html', context)
add action in your HTML form and POST in small case.
<form action="/your_backend_url_to_view/" method="post">
{% csrf_token %}
<label>recipe</label>
<p>{{form}}</p>
<label>ingredients</label>
{% for form in formset %}
<ul>
<label>name</label>
<li>{{ form.name }}</li>
<label>quantity</label>
<li>{{ form.quantity }}</li>
</ul>
{% endfor %}
<div>
<input type="submit" value="submit" class="button-33" role="button">
</div>
</form>

How to stop the user from being able to submit all other Django forms once a specific form is submitted?

I am trying to create an e-commerce site (CS50 Project 2) that allows its users to make comments, bids, and add listing items to their watchlists. I want the user who created the listing to be able to close the listing so that the winner (highest bidder) is displayed and no other of the forms will work (I also want to delete the listing from the watchlist). Currently, when the user who created the listing closes the listing, it saves (because it is a Django model), but the forms do not disappear, the listing does not delete off the watchlist, and the messages do not appear. How do I fix this? (I think it has to do with the if statement.)
views.py
#login_required(login_url='login')
def listing(request, id):
#gets listing
listing = get_object_or_404(Listings.objects, pk=id)
#code for comment and bid forms
listing_price = listing.bid
sellar = listing.user
comment_obj = Comments.objects.filter(listing=listing)
#types of forms
comment_form = CommentForm()
bid_form = BidsForm()
#watchlist_form = WatchListForm()
#closelisting_form = CloseListingForm()
#close listing code
if sellar == request.user:
closeListingButton = True
else:
closeListingButton = False
closeListing = ''
try:
has_closed = get_object_or_404(CloseListing, Q(
user=request.user) & Q(listing=listing))
except:
has_closed = False
if has_closed:
closeListing = False
else:
closeListing = True
#watchlist code
add_or_remove_watchlist = ''
try:
has_watchlists = get_object_or_404(WatchList, Q(
user=request.user) & Q(listing=listing))
print('--------------------------')
print(has_watchlists)
print('--------------------------')
except:
has_watchlists = False
if has_watchlists:
add_or_remove_watchlist = True
else:
print('it will from remove')
add_or_remove_watchlist = False
#code for the bid form
bid_obj = Bids.objects.filter(listing=listing)
other_bids = bid_obj.all()
max_bid =0
for bid in other_bids:
if listing.bid > max_bid:
max_bid = listing.bid
#checks if request method is post for all the forms
if request.method == "POST":
#forms
comment_form = CommentForm(request.POST)
bid_form = BidsForm(request.POST)
#watchlist code
if request.POST.get('add'):
WatchList.objects.create(user=request.user, listing=listing)
add_or_remove_watchlist = False
elif request.POST.get('remove'):
add_or_remove_watchlist = True
has_watchlists.delete()
#close listing code
if request.POST.get('close'):
CloseListing.objects.create(user=request.user, listings=listing)
closeListing = True
closeListingButton = False
else:
closeListing = False
#checks if comment form is valid
if comment_form.is_valid():
comment = comment_form.save(commit=False)
comment.listing = listing
comment.user = request.user
comment.save()
else:
return redirect('listing', id=id)
#checks if bid form is valid
if bid_form.is_valid():
print("bid form is valid")
new_bid = bid_form.cleaned_data.get("bid")
if (new_bid >= listing_price) and (new_bid > max_bid):
bid = bid_form.save(commit=False)
bid.listing = listing
bid.user = request.user
bid.save()
print("bid form is saving")
else:
print(bid_form.errors)
print("bid form is not saving")
return render(request, "auctions/listing.html",{
"auction_listing": listing,
"form": comment_form,
"comments": comment_obj,
"bidForm": bid_form,
"bids": bid_obj,
"message": "Your bid needs to be equal or greater than the listing price and greater than any other bids."
})
else:
print(bid_form.errors)
return redirect('listing', id=id)
#what happens if listing is closed
if closeListing == True:
closeListingButton = False
has_watchlists.delete()
winner = max_bid.user
return render(request, "auctions/listing.html",{
"auction_listing": listing,
"comments": comment_obj,
"bids": bid_obj,
"closeListingButton": closeListingButton,
"closeListing": closeListing,
"closedMessage": "This listing is closed.",
"winner": winner
})
else:
return redirect('listing', id=id)
return render(request, "auctions/listing.html",{
"auction_listing": listing,
"form": comment_form,
"comments": comment_obj,
"bidForm": bid_form,
"bids": bid_obj,
"watchlist": add_or_remove_watchlist,
"closeListingButton": closeListingButton
})
listing.html
<!--close listing code-->
{% if closeListing == True %}
<div>{{ closedMessage }}
<br>
{{ winner }} has won the auction!
</div>
{% endif %}
<form action = "{% url 'listing' auction_listing.id %}" method = "POST">
{% csrf_token %}
{% if closeListingButton == True %}
<input type = "submit" value = "Close Listing" name = "close">
<br>
<br>
{% endif %}
<!--watchlist form-->
{% if watchlist_message %}
<div>{{ watchlist_message }}</div>
{% endif %}
<form action = "{% url 'listing' auction_listing.id %}" method = "POST">
{% csrf_token %}
{% if watchlist == True %}
<input type="submit" value='Remove from Watchlist' name='remove'>
{% else %}
<input type="submit" value='Add to Watchlist' name='add'>
{% endif %}
</form>
<br>
<!--bid form-->
{% if message %}
<div>{{ message }}</div>
{% endif %}
<form action = "{% url 'listing' auction_listing.id %}" method = "POST" name = "newBid">
{% csrf_token %}
{{ bidForm }}
{{ bidForm.errors }}
<input type = "submit" value = "Place Bid">
</form>
{{ bidForm.errors }}
<br>
{% for bid in bids %}
<h6>${{ bid.bid }} <div style = "font-family: monospace;">Bid By: {{ bid.user }}</div></h6>
{% endfor %}
<!--comment form-->
<br>
<form action = "{% url 'listing' auction_listing.id %}" method = "POST">
{% csrf_token %}
{{ form }}
<input type = "submit" value = "Add Comment">
</form>
<br>
{% for comment in comments %}
<h6> {{ comment.comment }} <div style = "font-family: monospace;">Comment By: {{ comment.user }}</div></h6>
{% endfor %}

Django Model Form not showing errors after validation in clean()

Can you help me out with this. I hava a model form and I need to raise an error after validate two datetime objects in the clean method of the model form. This is what I have.
Forms
class HorariosDisponibles(forms.ModelForm):
tutor = forms.ModelChoiceField(queryset=Tutor.objects.all(),widget=forms.Select(attrs= {'class': 'input is-small is-rounded ' }),label='TUTOR',)
dia_hor_inicio =forms.DateTimeField(widget=forms.DateTimeInput(attrs= {'class': 'input is-small is-rounded ',}),label='Horario de Inicio', initial=datetime.date.today )
dia_hor_fin= forms.DateTimeField(widget=forms.DateTimeInput(attrs= {'class': 'input is-small is-rounded ' }),label='Horario de FinalizaciĆ³n', initial=datetime.date.today)
class Meta:
model = horarios_disp
fields = '__all__'
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields["dia_hor_inicio"].widget = DateTimeInput()
self.fields["dia_hor_inicio"].input_formats = ["%Y-%m-%dT%H:%M", "%Y-%m-%d %H:%M"]
self.fields["dia_hor_fin"].widget = DateTimeInput()
self.fields["dia_hor_fin"].input_formats = ["%Y-%m-%dT%H:%M", "%Y-%m-%d %H:%M"]
def clean(self):
cleaned_data = super(HorariosDisponibles, self).clean()
tutor = cleaned_data.get("tutor")
dia_hor_inicio = cleaned_data.get("dia_hor_inicio")
dia_hor_fin = cleaned_data.get("dia_hor_fin")
if dia_hor_inicio and dia_hor_fin:
if dia_hor_inicio.day != dia_hor_fin.day :
msg = 'Las fechas no pueden ser distintas'
self.add_error("dia_hor_inicio", msg)
raise forms.ValidationError("Las fechas no pueden ser distintas")
#NEITHER OF THIS APPROACHES WORKED
return cleaned_data
VIEWS
#login_required
def horario_tutor(request):
context = {
}
if request.method == 'POST':
print(request.POST)
form = HorariosDisponibles(request.POST)
if form.is_valid():
tutor = form.cleaned_data['tutor']
print("adentro")
dia_hor_inicio = form.cleaned_data['dia_hor_inicio']
dia_hor_fin = form.cleaned_data['dia_hor_fin']
tutor_horario = horarios_disp(
tutor=tutor, dia_hor_inicio=dia_hor_inicio, dia_hor_fin=dia_hor_fin)
tutor_horario.save()
context = {
'form': form
}
return redirect("home")
return render(request,"horarios_disponibles.html", context)
else:
form = HorariosDisponibles()
context['form'] = form
return render(request, "horarios_disponibles.html", context)
TEMPLATES
{% extends 'base.html' %}
{% block body %}
<section class="section">
<div class="columns is-vcentered">
<div class="column is-centered is-4 is-offset-2">
<form method="post">
{% csrf_token %}
{% for field in form %}
<div class="field">
{% for error in field.errors %}
<p class="help is-danger">{{ error }}</p>
{% endfor %}
<label for="{{field.id_for_label}}" class="label">{{ field.label }}</label>
{{ field }}
{% for non_field_error in form.non_field_errors %}
<p class="help is-danger">{{ non_field_error }}</p>
{% endfor %}
{% if field.help_text %}
<p class="help is-danger">{{ field.help_text|safe }}</p>
{% endif %}
</div>
{% endfor %}
<p class="control">
<button class="button is-link" type="submit">
Enviar
</button>
</p>
</form>
</section>
It validates if I put two different dates in the form, but it doesn't enter to is_valid() (because ther form is not valid). Render just the button of the template.
Try this:
if form.is_valid():
tutor = form.cleaned_data['tutor']
dia_hor_inicio = form.cleaned_data['dia_hor_inicio']
dia_hor_fin = form.cleaned_data['dia_hor_fin']
tutor_horario = horarios_disp(
tutor=tutor, dia_hor_inicio=dia_hor_inicio, dia_hor_fin=dia_hor_fin
)
tutor_horario.save()
context = {'form': form}
return redirect("home")
else:
context = {'error': 'whatever error you want to show here'}
return render(request, "horarios_disponibles.html", context)
# and probably some extra handling at the end in case there are errors
As a matter of fact, you won't need to declare the context = {} at the beginning of your code before if request.method == 'POST' because you're going to declare one on in the if-else statement anyways.

Showing error messages in template in DefaultUserCreationForm - django

I am having a problem in displaying an error message in the HTML page. I am using Django's default UserCreationForm for signup page. It has two password fields - one original and one for confirmation. When the user enters different passwords, I am getting at /signup/ whereas I want the error message to be displayed in the HTML page saying that the passwords didn't match. I have gone through the docs and I have added some related lines in my code, I don't know where I'm going wrong.
Here is my views.py:
def adduser(request):
if request.method == 'POST':
form = UserCreationForm(request.POST)
print(request.POST)
if(form.is_valid):
try:
user = employees.objects.get(emp_id=request.POST['username'] )
except employees.DoesNotExist:
user = None
print(user)
if( user != None ):
if request.POST['username'] in employees.objects.values_list('manager_id__emp_id',flat=True):
g = Group.objects.get(name='Managers')
newuser = form.save()
newuser.groups.add(g)
else:
g = Group.objects.get(name='Employees')
newuser = form.save()
newuser.groups.add(g)
return render(request,'login.html',{'form': form})
else:
form = UserCreationForm()
return render(request,'signup.html', {'form': form, 'msg': 'Enter valid employee id'})
else:
form = UserCreationForm()
return render(request,'signup.html', {'form': form})
and here is my signup.html:
<body>
<div class="container">
<div class="page-header">
<h1>Sign-up Here</h1>
</div>
{% block body %}
<form method="post">
{% csrf_token %}
<font color="orange" size="5px"><p> * Enter your Employee id, as username * </p></font>
{{ form.as_p }}
<font color="red"> {{ msg }} </font><br>
<font color="red"> {{ form.password1.errors }} </font><br>
<font color="red"> {{ form.password2.errors }} </font><br>
<br>
<button class="btn btn-success" type="submit"> Go! </button>
</form>
{% endblock %}
</div>
</body>
The problem is in this line :
if(form.is_valid):
This is not the correct way of testing form validation,
instead use:
if form.is_valid():
Also you dont need to declare form multiple times,it can be done single time.
Like this :
def adduser(request):
form = UserCreationForm(request.POST or None)
if request.method == 'POST':
print(request.POST)
if form.is_valid():
try:
user = employees.objects.get(emp_id=request.POST['username'] )
except employees.DoesNotExist:
user = None
print(user)
if( user != None ):
if request.POST['username'] in employees.objects.values_list('manager_id__emp_id',flat=True):
g = Group.objects.get(name='Managers')
newuser = form.save()
newuser.groups.add(g)
else:
g = Group.objects.get(name='Employees')
newuser = form.save()
newuser.groups.add(g)
return render(request,'login.html',{'form': form})
else:
form = UserCreationForm()
return render(request,'signup.html', {'form': form, 'msg': 'Enter valid employee id'})
return render(request,'signup.html', {'form': form})
And there can be diffrenmt type of erros, field and non_field_errors, so use someting like this :
{% if form.errors %}
{% for field in form %}
{% for error in field.errors %}
<div class="alert alert-danger">
<strong>{{ error|escape }}</strong>
</div>
{% endfor %}
{% endfor %}
{% for error in form.non_field_errors %}
<div class="alert alert-danger">
<strong>{{ error|escape }}</strong>
</div>
{% endfor %}
{% endif %}

User Registration after mobile verification

I want the user to submit the registration form and then redirect to another page to verify the number he entered in the mobile number field. If the verification is successful, my user should be created otherwise an error.
Currently my Register View looks like this:
def register_view(request):
template = "accounts/register.html"
print(request.user.is_authenticated())
next = request.GET.get('next')
print next
title = "Register"
form = UserRegisterForm(request.POST or None,)
if form.is_valid():
user = form.save(commit=False)
# number = user.mobile_number
# to_check = phonenumbers.parse(number,"TR")
# if phonenumbers.is_possible_number(to_check) and phonenumbers.is_valid_number(to_check):
# formatted_number = phonenumbers.format_number(to_check, phonenumbers.PhoneNumberFormat.E164)
# params = {
# 'api_key': ' api-key',
# 'api_secret': 'api-secret',
# 'number': formatted_number,
# 'brand': 'MobileVerification',
# }
# url = 'https://api.nexmo.com/verify/json?' + urllib.urlencode(params)
# response = urllib.urlopen(url)
# resp_dict = json.loads(response.read())
# request.session["user_request_id"] = resp_dict['request_id']
# messages.success(request,"A 4 digit pin has been successfully sent to your number.")
# return HttpResponseRedirect(reverse('pin_verify'))
# else:
# messages.error(request,"Enter a valid mobile number.")
# params2 = {
# }
# url = 'https://api.nexmo.com/verify/search/json?' + urllib.urlencode(params)
password = form.cleaned_data.get('password')
user.set_password(password)
user.save()
new_user = authenticate(username=user.mobile_number, password=password)
login(request, new_user)
if next:
return redirect(next)
return redirect("/")
context = {
"form": form,
"title": title
}
return render(request, template, context)
The commented code in the view is what I tried by getting the number and then redirecting but this is not how it should be.
My Register template looks like this:
{% extends "base.html" %}
{% load i18n %}
{% load crispy_forms_tags %}
{% block content %}
<div class='row'>
<div class='col-sm-6 col-sm-offset-3'>
<h1>Register for free!</h1>
<form method="post" action=".">
{% csrf_token %}
{{ form|crispy }}
<input class='btn btn-block btn-primary' type="submit" value="{% trans 'Join' %}" />
</form>
</div>
</div>
<hr/>
<div class='row'>
<div class='col-sm-6 col-sm-offset-3 text-align-center'>
<p>Need to Login?</p>
</div>
</div>
{% endblock %}

Categories

Resources