This question already exists:
Why is my form not being saved to my Django database? [duplicate]
Closed 2 years ago.
I'm trying to develop an e-commerce website using Django. I want to use Ajax to handle the view of my checkout form after it has been submitted. After the form is submitted, I want it to go to :
return HttpResponseRedirect(reverse(str(next_page))+"?address_added=True") , i.e http://127.0.0.1:8000/checkout/?address_added=True
But for some reason, it is not going there. Rather it's being redirected to http://127.0.0.1:8000/checkout/?csrfmiddlewaretoken=W4iXFaxwpdtbZLyVI0ov8Uw7KWOM8Ix5GcOQ4k3Ve65KPkJwPUKyBVcE1IjL3GHa&address=123+Main+Street&address2=&state=MA&country=USA&zipcode=55525&phone=%28877%29+314-0742&billing=on
As a result, the form data is also not getting saved. I was thinking if it were because of the new version of Django.
What I want to do is that after they submit the place order button, the form is going to be None, i.e disappear and then I would add a credit card form there for payment. But it is not happening. What is wrong here? How can I do this or is there a better way to do this?
My forms.py:
class UserAddressForm(forms.ModelForm):
class Meta:
model = UserAddress
fields = ["address", "address", "address2", "state", "country", "zipcode", "phone", "billing"]
My accounts.views.py:
def add_user_address(request):
try:
next_page = request.GET.get("next")
except:
next_page = None
if request.method == "POST":
form = UserAddressForm(request.POST)
if form.is_valid():
new_address = form.save(commit=False)
new_address.user = request.user
new_address.save()
if next_page is not None:
return HttpResponseRedirect(reverse(str(next_page))+"?address_added=True")
else:
raise Http404
else:
raise Http404
My orders.views.py:
#login_required()
def checkout(request):
try:
the_id = request.session['cart_id']
cart = Cart.objects.get(id=the_id)
except:
the_id = None
return redirect(reverse("myshop-home"))
try:
new_order = Order.objects.get(cart=cart)
except Order.DoesNotExist:
new_order = Order(cart=cart)
new_order.cart = cart
new_order.user = request.user
new_order.order_id = id_generator()
new_order.save()
except:
return redirect(reverse("cart"))
try:
address_added = request.GET.get("address_added")
except:
address_added = None
if address_added is None:
address_form = UserAddressForm()
else:
address_form = None
if new_order.status == "Finished":
#cart.delete()
del request.session['cart_id']
del request.session['items_total']
return redirect(reverse("cart"))
context = {"address_form": address_form, "cart": cart}
template = "orders/checkout.html"
return render(request, template, context)
My urls.py:
path('ajax/add_user_address', accounts_views.add_user_address, name='ajax_add_user_address'),
My checkout.html:
<form method="POST" action="{% url 'ajax_add_user_address' %}?redirect=checkout">
{% csrf_token %}
<fieldset class="form-group">
{{ address_form|crispy }}
</fieldset>
<div class="form-group">
<button class="btn btn-outline-dark" type="submit">Place Order</button>
</div>
</form>
Related
I want to insert latitude and long using python Django. I use code but does not work when click on the button it shows null in DB.
models.py
class UserLocation(models.Model):
map_id = models.AutoField(primary_key=True)
map_u_address = models.CharField(max_length=250, null=True)
latitude = models.DecimalField(max_digits=11, decimal_places=7, null=False, blank=True)
longitude = models.DecimalField(max_digits=11, decimal_places=7, null=False, blank=True)
view.py
def save_location(request):
if request.method == 'POST':
form = request.POST
latitude = form.get('latitude')
longitude = form.get('longitude')
user_id = request.session['user_id']
insert_data = UserLocation.objects.create( latitude=latitude,longitude=longitude,
)
if insert_data:
json_data = {'msg': "Insert data successfully", 'state_val': 1}
return JsonResponse(json_data)
else:
json_data = {'msg': "Data not saved", 'state_val': 2}
return JsonResponse(json_data)
else:
return render(request, 'map_1.html')
how I can do an update (edit) for latitude and long using (form.py) python Django?
In forms.py
from django.forms import ModelForm
# Import your UserLocation model
from .models import UserLocation
# Create your forms here
class UserLocationForm(ModelForm):
class Meta:
model = UserLocation
fields = ('latitude', 'longitude')
In views.py
from .forms import UserLocationForm
def save_location(request):
form = UserLocationForm()
context = {}
context['form'] = form
if request.method == 'POST':
form = UserLocationForm(request.POST)
user_id = request.session['user_id']
if form.is_valid():
insert_data = form.save()
if insert_data:
json_data = {'msg': "Insert data successfully", 'state_val': 1}
return JsonResponse(json_data)
else:
json_data = {'msg': "Data not saved", 'state_val': 2}
return JsonResponse(json_data)
else:
# Update form in context dictionary
context['form'] = form
# Re-render page with prefilled data
return render(request, 'map_1.html', context)
else:
return render(request, 'map_1.html', context)
In template
<form action="" method="post">
{% csrf_token %}
{{ form }}
<input type="submit">
</form>
For Updating location
In views.py
def update_location(request, location_id):
try:
# Get location from db for location_id
location = UserLocation.objects.get(id=location_id)
except UserLocation.DoesNotExist:
return # redirect user back as the location id is invalid
# Populate the form with data of requested instance
form = UserLocationForm(instance=location)
context = {}
context['form'] = form
if request.method == 'POST':
form = UserLocationForm(request.POST)
user_id = request.session['user_id']
if form.is_valid():
form.save()
return # Redirect user to somewhere
# When the posted data is invalid
else:
# Update form in context dictionary
context['form'] = form
# Re-render page with prefilled data
return render(request, 'update_location.html', context)
else:
return render(request, 'update_location.html', context)
In update_location.html
{% block body %}
<div class="container-fluid">
<form method="POST" action="">
{% csrf_token %}
{{ form }}
<input type="submit" value="Upload" class="btn btn-primary">
</form>
</div>
{% endblock body %}
In urls.py
path('update_location/<int:location_id>/', views.update_location, name="update-location"),
Got some forms in my view...
I want that only what I have submitted is changed in the database. So that no forms overwrite each other. How can I do this with my view?
I even noticed that the order in which each '..._form.is_valid()' is, makes a difference in what gets overwritten
views.py
#login_required
def DashboardView(request):
browser = str(request.user_agent.browser.family)
user = str(request.user)
short_user = user[0:7] + "..."
try:
radius = request.user.fieldradius
except FieldRadius.DoesNotExist:
radius = FieldRadius(user=request.user)
try:
font_size = request.user.fontsize
except FontSize.DoesNotExist:
font_size = FontSize(user=request.user)
try:
change_color = request.user.colors
except Colors.DoesNotExist:
change_color = Colors(user=request.user)
try:
toggle_settings = request.user.togglesettings
except ToggleSettings.DoesNotExist:
toggle_settings = ToggleSettings(user=request.user)
try:
page_details = request.user.pagedetails
except PageDetails.DoesNotExist:
page_details = PageDetails(user=request.user)
if request.method == 'POST':
form = FieldForm(request.POST, instance=Field(user=request.user))
togglesettings_form = ToggleSettingsForm(
request.POST, instance=toggle_settings)
radius_form = FieldRadiusForm(request.POST, instance=radius)
change_color_form = ColorsForm(request.POST, instance=change_color)
fontsize_form = FontSizeForm(request.POST, instance=font_size)
pagedetails_form = PageDetailsForm(
request.POST, request.FILES, instance=page_details)
if togglesettings_form.is_valid():
togglesettings_form.save()
return redirect('/dashboard/#panel1')
if form.is_valid():
time.sleep(1.5)
obj = form.save(commit=False)
obj.creator_adress = get_client_ip(request)
obj.save()
return redirect('/dashboard')
if radius_form.is_valid():
radius_form.save()
return redirect('/dashboard')
if fontsize_form.is_valid():
fontsize_form.save()
return redirect('/dashboard')
if change_color_form.is_valid():
change_color_form.save()
return redirect('/dashboard')
if pagedetails_form.is_valid():
pagedetails_form.save()
return redirect('/dashboard')
else:
form = FieldForm()
radius_form = FieldRadiusForm(instance=radius)
fontsize_form = FontSizeForm(instance=font_size)
change_color_form = ColorsForm(instance=change_color)
pagedetails_form = PageDetailsForm(instance=page_details)
togglesettings_form = ToggleSettingsForm()
return render(request, 'dashboard.html', {'form': form, 'togglesettings_form': togglesettings_form, 'fontsize_form': fontsize_form, 'change_color_form': change_color_form, 'browser': browser, 'short_user': short_user, 'radius_form': radius_form, 'radius': radius, 'pagedetails_form': pagedetails_form})
If I submit a form, for example the togglesettings_form, it looks like this in the database:
After that, I submit another form, for example the fontsize_form. The fontsize_form will be saved but then the togglesettings_form will be resetted:
Forms and models, if you want to see them:
https://pastebin.com/PhaFCdBP
I have read something like
if ...form in request.POST:
do this
But I dont know how to implement that in my view
Usually I name the submit button on the form something like "my-form"
Then you can just go:
if "my-form" in request.POST:
then do what you need to do
View example:
if 'load_doc' in request.POST:
file = request.FILES['document_file']
doc = documents(client=current_client,document_name=request.POST['document_name'],document_file=file)
doc.save()
html example:
<form method="post" action="" enctype="multipart/form-data">
{% csrf_token %}
<div class="panel-body">{{ single_load_form|crispy }}</div>
<div class="panel-footer"><button class="btn btn-primary" name="load_doc">Submit</button></form></div>
I want to show a form for invitation. I have created a form but when i go to the url /invitations/request, the invalid block is shown not the template with form. What might be the reason?
url(r'^request/$', requestInvitation, name='request-invitation'),
#csrf_exempt
def requestInvitation(request):
form = InviteForm(request.POST or None)
response_data = {}
if form.is_valid():
join = form.save(commit=False)
email = form.cleaned_data.get('email')
already_join, created = Invitation.objects.get_or_create(email=email)
if created:
already_join.invite_code = get_invite_code()
already_join.save()
response_data['result'] = "Thank you for your interest"
response_data['email'] = email
print ('response_data', response_data)
return HttpResponse(json.dumps(response_data),content_type="application/json")
else:
return HttpResponse(json.dumps({'result': 'Error message'}))
# return HttpResponseRedirect('/')
context = {"form": form}
return render(request, 'invitation/invitation.html', context)
<form method="POST" class="invitation-form vcenter" action=".">
{% csrf_token %}
<div class="ui action input">
<input type="email" class="requested_email" name="email" placeholder="Email address">
<button class="ui button primary">Request Invite</button>
</div>
</form>
I think, you need to separate out the POST call. I mean, you need to check if the request method is POST or not. Something like this:
if request.method == 'POST': # If the form has been submitted...
response_data = {}
if form.is_valid():
join = form.save(commit=False)
email = form.cleaned_data.get('email')
already_join, created = Invitation.objects.get_or_create(email=email)
if created:
already_join.invite_code = get_invite_code()
already_join.save()
response_data['result'] = "Thank you for your interest"
response_data['email'] = email
print ('response_data', response_data)
return HttpResponse(json.dumps(response_data),content_type="application/json")
else:
return HttpResponse(json.dumps({'result': 'Error message'}))
# return HttpResponseRedirect('/')
else:
# An unbound form
Here's the workflow for your request:
A GET request is made (you're just visiting /invitations/request. So request.POST is an empty {}.
form = InviteForm(request.POST or None). Thus, the InviteForm is not valid.
if form.is_valid(): is False.
else: return HttpResponse(json.dumps({'result': 'Error message'})). So, the else clause is executed, which returns a JSON response, which you're showing in your template.
Now, for the solution:
#csrf_exempt
def requestInvitation(request):
form = InviteForm()
response_data = {}
if request.method == 'POST':
# This is a POST request, so request.POST will not be {}
form = InviteForm(request.POST)
if form.is_valid():
join = form.save(commit=False)
email = form.cleaned_data.get('email')
already_join, created = Invitation.objects.get_or_create(email=email)
if created:
already_join.invite_code = get_invite_code()
already_join.save()
response_data['result'] = "Thank you for your interest"
response_data['email'] = email
print ('response_data', response_data)
return HttpResponse(json.dumps(response_data),content_type="application/json")
else:
return HttpResponse(json.dumps({'result': 'Error message'}))
context = {'form': form}
return render(request, 'invitation/invitation.html', context)
Outcome needed : My main aim is to get a guest login that is user adds email address and then django checks for the email in the database if it finds one then error is shown else user is logged in.
Problem : In my form when I add an email address then Django adds the email in the database but if I add that email again no error is shown also I am not being logged in Django.
Version Using:
appdirs==1.4.2
cffi==1.9.1
cryptography==1.7.2
Django==1.8.4
django-crispy-forms==1.6.1
django-registration-redux==1.4
enum34==1.1.6
idna==2.4
ipaddress==1.0.18
olefile==0.44
packaging==16.8
Pillow==4.0.0
pyasn1==0.2.3
pycparser==2.17
pyOpenSSL==16.2.0
pyparsing==2.1.10
requests==2.13.0
six==1.10.0
forms.py
from django import forms
from django.contrib.auth import get_user_model
User = get_user_model()
class GuestCheckoutForm(forms.Form):
email = forms.EmailField()
email2 = forms.EmailField(label='Verify Email')
def clean_email2(self):
email = self.cleaned_data.get("email")
email2 = self.cleaned_data.get("email2")
if email == email2:
user_exists = User.objects.filter(email=email).count()
if user_exists != 0:
raise forms.ValidationError("This User already exists. Please login instead.")
return email2
else:
raise forms.ValidationError("Please confirm emails are the same")
views.py
from django.contrib.auth.forms import AuthenticationForm
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect, Http404, JsonResponse
from django.shortcuts import render, get_object_or_404, redirect
from django.views.generic.base import View
from django.views.generic.detail import SingleObjectMixin, DetailView
from django.views.generic.edit import FormMixin
# Create your views here.
from orders.forms import GuestCheckoutForm
from orders.models import UserCheckout
from products.models import Variation
from .models import Cart, CartItem
class ItemCountView(View):
def get(self, request, *args, **kwargs):
if request.is_ajax():
cart_id = self.request.session.get("cart_id")
if cart_id == None:
count = 0
else:
cart = Cart.objects.get(id=cart_id)
count = cart.items.count()
request.session["cart_item_count"] = count
return JsonResponse({"count": count})
else:
raise Http404
class CartView(SingleObjectMixin, View):
model = Cart
template_name = "carts/view.html"
def get_object(self, *args, **kwargs):
self.request.session.set_expiry(0) #5 minutes
cart_id = self.request.session.get("cart_id")
if cart_id == None:
cart = Cart()
cart.save()
cart_id = cart.id
self.request.session["cart_id"] = cart_id
cart = Cart.objects.get(id=cart_id)
if self.request.user.is_authenticated():
cart.user = self.request.user
cart.save()
return cart
def get(self, request, *args, **kwargs):
cart = self.get_object()
item_id = request.GET.get("item")
delete_item = request.GET.get("delete", False)
item_added = False
if item_id:
item_instance = get_object_or_404(Variation, id=item_id)
qty = request.GET.get("qty", 1)
try:
if int(qty) < 1:
delete_item = True
except:
raise Http404
cart_item, created = CartItem.objects.get_or_create(cart=cart, item=item_instance)
if created:
item_added = True
if delete_item:
cart_item.delete()
else:
cart_item.quantity = qty
cart_item.save()
if not request.is_ajax():
return HttpResponseRedirect(reverse("cart"))
#return cart_item.cart.get_absolute_url()
if request.is_ajax():
try:
total = cart_item.line_item_total
except:
total = None
try:
subtotal = cart_item.cart.subtotal
except:
subtotal = None
try:
cart_total = cart_item.cart.total
except:
cart_total = None
try:
tax_total = cart_item.cart.tax_total
except:
tax_total = None
try:
total_items = cart_item.cart.items.count()
except:
total_items = 0
data = {
"deleted": delete_item,
"item_added": item_added,
"line_total": total,
"subtotal": subtotal,
"cart_total": cart_total,
"tax_total": tax_total,
"total_items": total_items
}
return JsonResponse(data)
context = {
"object": self.get_object()
}
template = self.template_name
return render(request, template, context)
class CheckoutView(FormMixin, DetailView):
model = Cart
template_name = "carts/checkout_view.html"
form_class = GuestCheckoutForm
def get_object(self, *args, **kwargs):
cart_id = self.request.session.get("cart_id")
if cart_id == None:
return redirect("cart")
cart = Cart.objects.get(id=cart_id)
return cart
def get_context_data(self, *args, **kwargs):
context = super(CheckoutView, self).get_context_data(*args, **kwargs)
user_can_continue = False
user_check_id = self.request.session.get("user_checkout_id")
if not self.request.user.is_authenticated() or user_check_id == None:# or if request.user.is_guest:
context["login_form"] = AuthenticationForm()
context["next_url"] = self.request.build_absolute_uri()
elif self.request.user.is_authenticated() or user_check_id != None:
user_can_continue = True
else:
pass
context["user_can_continue"] = user_can_continue
context["form"] = self.get_form()
return context
def post(self, request, *args, **kwargs):
self.object = self.get_object()
form = self.get_form()
if form.is_valid():
email = form.cleaned_data.get("email")
user_checkout, created = UserCheckout.objects.get_or_create(email=email)
request.session["user_checkout_id"] = user_checkout.id
print user_checkout
return self.form_valid(form)
else:
return self.form_invalid(form)
def get_success_url(self):
return reverse("checkout")
checkout_view.html
{% extends "base.html" %}
{% load i18n %}
{% load crispy_forms_tags %}
{% block content %}
{% if not user_can_continue %}
<div class='col-sm-6'>
<p class='lead'>Continue as Guest</p>
<form method='POST' action=''>{% csrf_token %}
{{ form|crispy }}
<input type='submit' class='btn btn-success' value='Continue as Guest' />
</form>
</div>
<div class='col-sm-6'>
<p class='lead'>Login to Continue</p>
<form method='POST' action="{% url 'auth_login' %}"> {% csrf_token %}
{{ login_form|crispy }}
<input type='hidden' name='next' value='{{ next_url }}' />
<input type='submit' class='btn btn-success' value='Login' />
</form>
<p class='text-center'>
<p>{% trans "Forgot password" %}? {% trans "Reset it" %}!</p>
<p>{% trans "Not member" %}? {% trans "Register" %}!</p>
</p>
</div>
{% endif %}
{% endblock %}
models.py
from django.conf import settings
from django.db import models
# Create your models here.
class UserCheckout(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, null=True, blank=True) #not required
email = models.EmailField(unique=True) #--> required
def __unicode__(self): #def __str__(self):
return self.email
As such I am getting no error but the problems stated above are occurring
The clean_* methods in django should always return the value.
def clean_email2(self):
email = self.cleaned_data.get("email")
email2 = self.cleaned_data.get("email2")
if email == email2:
# Query your UserCheckout model. Not the auth one!
if UserCheckout.objects.filter(email=email).exists():
raise forms.ValidationError("This User already exists. Please login instead.")
else:
raise forms.ValidationError("Please confirm emails are the same")
return email2
I have a view called "search" which stores POST input as "search_id" but "search_id" is only available in the scope of the view "search". I want to be able to access the variable "search_id" in my view "dispTable".
Disclaimer- if this part of my question makes no sense, plz ignore: I understand that I could add an additional parameter to dispTable which would allow me to pass the search_id into dispTable in a return statement but what if I wanted to be able to access search_id in multiple views.
def search(request):
if request.method == 'POST' :
search_id = request.POST.get('textfield', None)
try:
return dispTable(request)
except Person.DoesNotExist:
return HttpResponse("no such user")
except Person.MultipleObjectsReturned :
#return dispTable(request, search_id)
return showResults(request)
else :
return render(request, 'People/search.html')
def dispTable(request) :
table = authTable(Person.objects.filter(MAIN_AUTHOR = 'search_id'))
RequestConfig(request).configure(table)
#return render(request, 'People/tableTemp.html', {'table':table})
return render(request, 'People/tableTemp.html', {"table" : Person.objects.filter(MAIN_AUTHOR = search_id)})
I also tried using a form, but I still did not know how to access the input variable in additional views, like dispTable
from django import forms
class SearchForm(forms.Form) :
search_id = forms.CharField(max_length=100)
def process(self) :
search_id = self.cleaned_data['search_id']
def search(request) :
if request.method == 'POST' :
form = SearchForm(request.POST)
if form.is_valid() :
form.process()
return dispTable(request)
else :
form = SearchForm()
return render (request, 'People/search.html')
And here is my html file:
<form method="POST" action="send/">
{% csrf_token %}
<input type="text" name="textfield">
<button type="submit">Upload text</button>
</form>