how do I save form data from a different url template - python

how do I not save the form data until the transaction is done which is in a different URL, if the shipping form and the payment options were to be in the same URL then there wouldn't be this problem but it's not so how do I go about this? thx!
views.py
def checkout(request):
if request.method == 'POST':
form = ShippingForm(request.POST)
if form.is_valid():
new_shipping = form.save(commit=False)
new_shipping.customer = customer
new_shipping.order = order
#how do I not save the data until the transaction is successful
new_shipping.save()
return redirect('store:checkout_shipping')
else:
form = ShippingForm()
else:
form = ShippingForm()
context = {"form": form}
return render(request, 'shop/checkout.html', context)
def checkout_payment(request):
return render(request, 'shop/checkout_payment.html', context)
urls.py
path('checkout', views.checkout, name="checkout"),
path('checkout_payment', views.checkout_payment, name="checkout_payment"),
forms.py
class ShippingForm(forms.ModelForm):
address_one = forms.CharField(max_length=200)
address_two = forms.CharField(max_length=200)

I think what might help is to use sessions. Django will store this temporary data using session cookies. Here's the idea:
from django.forms.models import model_to_dict
def checkout(request):
form = ShippingForm(request.POST or None)
if form.is_valid():
new_shipping = form.save(commit=False)
new_shipping.customer = customer
new_shipping.order = order
request.session['partial-data'] = model_to_dict(new_shipping)
return redirect('store:checkout_shipping')
context = {"form": form}
return render(request, 'shop/checkout.html', context)
def checkout_payment(request):
# I'm guessing here is where the rest of the data
# is to be filled in. The data of the previous view
# is already here stored in the cookie
full-form-data = request.session['partial-data']
full-form-data['extra-field-1'] = 'something'
full-form-data['extra-field-2'} = 'something else'
form = ShippingForm(full-form-data or None)
if form.is_valid():
form.save()
context = {
'form': form
}
return render(request, 'shop/checkout_payment.html', context)

Related

Django modelform initial value doesn't work

def createProject(request):
form = ProjectForm()
initial_data = {
'responsible':request.user.username
}
yonetici = Project(host=request.user)
if request.method == 'POST':
form = ProjectForm(request.POST, instance=yonetici,initial=initial_data)
if form.is_valid():
form.save()
return redirect('home')
context = {'form': form}
return render(request, 'base/project_form.html', context)
i tried many solutions but i couldnt make it work where am i doing wrong?

Django: How to get a users coordinates (latitude, longitude) in a view?

I need to be able to check the user's location before determining where their redirect will be sent. Is there an easy way to do this in Django/Python?
views.py
#login_required
def update(request):
if users coords in range(....):
form = UpdateForm(request.POST or None)
if request.method == "POST":
if form.is_valid():
update = form.save(commit=False)
update.user = request.user
update.save()
value = form.cleaned_data['update']
return redirect('main-home')
return render(request, "main/update.html", {'form': form})
else:
return render(request, "main/error.html")
Try
from django.contrib.gis.utils import GeoIP
g = GeoIP()
lat,lng = g.lat_lon(user_ip)

Use the same TemplateView for create and update

I have this TemplateView:
class DamageEntry(TemplateView):
template_name = "damage/damageadd.html"
def get(self, request):
general = General.objects.get(pk=1)
form = DamageEntryForm()
args = {'form': form,
'general': general,
}
return render(request, self.template_name, args)
def post(self, request):
general = General.objects.get(pk=1)
form = DamageEntryForm(request.POST)
form.non_field_errors()
if form.is_valid():
post = form.save(commit=False)
if self.request.user.is_authenticated():
post.user = request.user
post.userip = get_client_ip(request) # το IP του χρήστη
location = get_cocation(post.lat, post.lng)
post.location = location
post.formatted_address= location.formatted_address
post.entry_date = datetime.datetime.now(tz=timezone.utc)
post.save()
form = DamageEntryForm()
args = {'form': form,
'general': general
}
return http.HttpResponseRedirect('damage/add/')
else:
print('form is not valid')
print(form.errors)
# form = DamageEntryForm()
args = {'form': form,
'general': general
}
return render(request, self.template_name, args)
It works fine for create new record.
I want to use thw same view for update, because of the extra code on Post section.
I use this URL for update:
# /damage/damage/list/1
url(r'damage/list/(?P<pk>[0-9]+)/$', views.DamageEntry.as_view(), name="damage-by-id"),
Can I do this? How can I pass pk for create and update record?

Editing inlineformsets associated with parent form

I have created an invoice and items in it using Modelform and inlineforset_factory.
Now I am trying to create edit form, but I am getting MultiValueDictKeyError when I try to edit those inline fields. If I just create new inlineformsets I can edit Modelform just fine. After one hour of googling I am no closer to finding any solution.
maxItems = 20
ItemFormSet = inlineformset_factory(Invoice, Item, can_delete=True, extra=maxItems)
Creating of new invoice (working perfectly)
def new_invoice(request):
if request.method == "POST":
form = InvoiceForm(request.POST)
if form.is_valid():
invoice = form.save(commit=False)
item_formset = ItemFormSet(request.POST,instance=invoice)
if item_formset.is_valid():
invoice.dateCreated = datetime.datetime.now()
invoice.save()
item_formset.save()
return redirect('list/new0')
else:
form = InvoiceForm()
item_formset = ItemFormSet(instance=Invoice())
return render(request, "form.html", {"form": form, "item_formset": item_formset })
Editing invoice (MultiValueDictKeyError)
def edit_invoice(request, invoice_id):
invoicer = get_object_or_404(Invoice, pk=invoice_id)
if request.method == "POST":
form = InvoiceForm(request.POST, instance=invoicer)
if form.is_valid():
invoice = form.save(commit=False)
item_formset = ItemFormSet(request.POST,instance=invoice)
if item_formset.is_valid():
invoice.dateCreated = datetime.datetime.now()
invoice.save()
item_formset.save()
return redirect('list/new0')
else:
form = InvoiceForm(instance=invoicer)
item_formset = ItemFormSet(instance=invoicer)
return render(request, "form.html", {"form": form, "item_formset": item_formset })
You have two variables, invoicer and invoice that I assume are different instances of the same object. Try re-writing your edit view like this:
def edit_invoice(request, invoice_id):
invoice = get_object_or_404(Invoice, pk=invoice_id)
if request.method == 'POST':
form = InvoiceForm(request.POST, instance=invoice)
formset = ItemFormSet(request.POST, instance=invoice)
if form.is_valid() and formset.is_valid():
invoice = form.save()
invoice.dateCreated = datetime.datetime.now()
invoice.save()
formset.save()
return redirect('list/new0')
else:
form = InvoiceForm(instance=invoice)
formset = ItemFormSet(instance=invoice)
context = {
'form': form,
'formset': formset,
}
return render(request, 'form.html', context)
Let me know if that works for you.
Ok, so I've found that problem was not in the views.py nor in forms.py, but in template. Because I've built the template without using {{form.as_p/table/...}} The form had some extra inputs - DELETE,ID and foreignKey... after adding them to my for loop, everything works fine :)

List uploaded files in django

How can I list files after they have been uploaded? I want to display them so they can be viewed and downloaded later.
Here is my code.
models.py
class UploadFile(models.Model):
file = models.FileField(upload_to='files/%Y/%m/%d')
forms.py
class UploadFileForm(forms.ModelForm): pass
class Meta:
model = UploadFile
views.py
#login_required(login_url='/accounts/login/')
def home(request):
if request.method == 'POST':
form = UploadFileForm(request.POST, request.FILES)
if form.is_valid():
new_file = UploadFile(file = request.FILES['file'])
new_file.save()
return HttpResponseRedirect(reverse('main:home'))
else:
form = UploadFileForm()
data = {'form': form}
return render_to_response('upload.html', data,
context_instance=RequestContext(request))
No need to get file back from form and save it - just save it using your model. View have to be something like this:
#login_required(login_url='/accounts/login/')
def home(request):
if request.method == 'POST':
form = UploadFileForm(request.POST, request.FILES)
if form.is_valid():
form.save() # saving model instance
return HttpResponseRedirect(reverse('main:home'))
else:
form = UploadFileForm()
data = {'form': form}
return render_to_response('upload.html', data, context_instance=RequestContext(request))
and after this you can take all uploaded files from your model:
files = [upload_file.file for upload_file in UploadFile.objects.all()]
and show them to user

Categories

Resources