Django view is not redirecting properly - python

I'm facing some difficulties to render pages with Django shortcuts. My workflow is quite simple:
Users go a page where they can view some project data (detail_project)
If they want to update the project data, they should click a button that will send a POST request and loads update_project page. This page is loaded with current project data.
Users update and submit new data. After submission, they are returned to detail_project page.
My view is like this:
def update_project(request):
if request.method == 'POST':
if 'update_project_submit' in request.POST:
# updates project with form data and returns to detail project page
return redirect('detail_project', project_name=project_name)
else:
# loads project original data into the form
return render(request, 'project/update_project.html', context)
def detail_project(request, project_name):
if request.method == 'POST':
if 'update_project' in request.POST:
return update_project(request)
else:
# does another stuff
else:
# shows project details
return render(request, 'project/detail_project.html', context)
urls.py:
url(r'^project/update/$', views.update_project, name='update_project'),
url(r'^project/details/(?P<project_name>[a-zA-Z][a-zA-Z0-9-_]+)/$', views.detail_project, name='detail_project'),
And update_project.html:
<form class="form-horizontal" role="form" action="" method="post">
{% csrf_token %}
{% for field in form %}
<div class="form-group">
<div class="col-sm-3">
<label for="{{ field.id_for_label }}" class="control-label">{{ field.label }}</label>
</div>
<div class="col-sm-9">
{{field}}
</div>
<div class="col-sm-12">
{{ field.help_text }}
</div>
</div>
{{field.non_field_errors }}
{{field.errors}}
{% endfor %}
<button type="submit" name="update_project_submit" class="btn btn-primary">Submit</button>
</form>
[ Update ]
Forms.py
class UpdateProjectForm(forms.Form):
project_name_validator = RegexValidator(r'^[a-zA-Z][a-zA-Z0-9-_]{1,31}$', constants.PROJECT_NAME_INVALID)
project_name = forms.CharField(required=True, widget=forms.TextInput(attrs={'required': 'true'}), validators=[project_name_validator])
project_description = forms.CharField(required=True, widget=forms.Textarea(attrs={'style':'resize:none;', 'required': 'true'}))
project_expiration = forms.DateField(required=False, widget=forms.TextInput(attrs={'class':'datepicker'}))
def __init__(self, *args, **kwargs):
super(UpdateProjectForm, self).__init__(*args, **kwargs)
self.fields['project_name'].label = "Project Name:"
self.fields['project_description'].label = "Project Description:"
self.fields['project_expiration'].label = "Expiration Date:"
The problem is that I cannot update my project. My page loads the form properly (update_project) with the current data (step 2), but when I submit it (click the Submit button, I'm redirected to detail project page without entering the if 'update_project_submit' in request.POST: statement. Maybe my workflow is wrong. I cannot figure it out.
I printed my request, and I've really cofirmed that when I submit the form, I'm receiving a POST request to detail_project.
Is there something I am missing? Or am I trying to do something wrong according to Django's logic?

Use
if request.POST.get('update_project_submit', False):
instead of
if 'update_project_submit' in request.POST:

Related

Django submit file form won't save to models through front-end

So the goal is to get the user to upload images inside the application, and for the images to be displayed on the screen.
The problem is that the forms will not save to the models I made. I am following Django Central https://djangocentral.com/uploading-images-with-django/ for guidance for uploading my images.
What I have at the moment is where the user can type inside the form for their caption and where the user can select a file for their image, but nothing happens when they click the upload button. All that happens, is that it redirects me to the homepage for some reason, but I can fix that later. The only way for the images to be displayed on the website is if I manually go into the admin panel and upload the image there. If anyone could help I would much appreciate it.
view.py
def profile(request):
if request.method == "POST":
form = User_Profile_Form(data = request.POST, files = request.FILES)
if form.is_valid():
form.save()
obj = form.instance
return render(request, "main/profile.html", {"obj":obj})
else:
form = User_Profile_Form()
img = User_Profile.objects.all()
return render(request,"main/profile.html", {"img":img, "form":form})
models.py
class User_Profile(models.Model):
caption = models.CharField(max_length = 100)
image = models.ImageField(upload_to = "img/%y", blank=True)
def __str__(self):
return self.caption
forms.py
from django import forms
from .models import User_Profile
class User_Profile_Form(forms.ModelForm):
class Meta:
model = User_Profile
fields = ("caption", "image")
profile.html
<div class="container">
<form action="." method="post" enctype="multipart/form-data">
{% csrf_token %}
{{form.as_p}}
<button type="submit" class="btn btn-lg btn-success">Upload</button>
</form>
{% if obj %}
<h3>Succesfully uploaded : {{img_obj.caption}}</h3>
<img src="{{ obj.image.url}}" alt="image" class="img-thumbnail" >
{% endif %}
<hr>
{% for x in img %}
{% if forloop.first %}<div class="row ">{% endif %}
<div class="col-lg-4 col-md-4 col-12" >
<div class="text-center mt-2">
<img src="{{x.image.url}}" height="70%" width="70%" class="img-thumbnail" alt="...">
<h2 class="text-center" >{{x.caption}}</h2></div>
</div>
{% if forloop.counter|divisibleby:3 %}
</div>
<div class=row>{% endif %}
{% if forloop.last %}</div>{% endif %}
{% endfor %}
</div>
In the template change the action:
from:
<form action="." method="post" enctype="multipart/form-data">
To:
<form action="" method="post" enctype="multipart/form-data">
. redirects you to the home page.
in views.py
def profile(request):
if request.method == "POST":
form = User_Profile_Form(data = request.POST, files = request.FILES)
if form.is_valid():
form.save()
obj = form.instance
return render(request, "main/profile.html", {"obj":obj, "form":form})
else:
form = User_Profile_Form()
img = User_Profile.objects.all()
return render(request,"main/profile.html", {"img":img, "form":form})
i know what you want to do, i did it on my project, here is my code, edited for your self
views.py
pimageupdate = ProfileImageUpdate(request.POST,request.FILES, instance=request.user.userprofile)
if pimageupdate.is_valid():
pimageupdate.save()
should i note that pimageupdate is getting the form from forms.py
and you should add user in your {{}} code like this
{{user.userprofile.default_profile_picture}}
change "post" in your form tag to "POST"
hope this work, let me know if you tried them

Failure in multiple times Parameters Passing in Django (Python)

I am new to django. My current plan is displaying user name on different html pages, once user have successfully logged in. At the moment, the page after login page can successfully display the user name with the django tag in html which is {{ username }}. But once it has successfully passed to my second page, my second page CAN NOT pass it to my third page. The attached images are my html codes for second.html and third.html. Thanks for your help.
Second.html
<form action="/SecondPageSub/" method="POST">
{% csrf_token %}<br>
<b>NTID:</b><br>
<label name="usrnm">{{username}}</label>
<button type="submit" name="SecondPageSub">
SUBMIT
</button>
</form>
Third.html
<form action="/ThirdPageSub/" method="POST">
{% csrf_token %}<br>
<b>NTID:</b><br>
<label name="usrnm">{{username}}</label>
<button type="submit" name="ThirdPageSub">
SUBMIT
</button>
</form>
Python codes in view.py
def ActionGet(request):
if request.method == "POST":
if 'login' in request.POST:
usrname = request.POST.get("usrnm", None)
passwrd = request.POST.get("pwd", None)
dic={}
dic['username']=usrname
dic['password']=passwrd
return render(request, "Second.html",dic)
if 'SecondPageSub' in request.POST:
usrname = request.POST.get("usrnm", None)
dic={}
dic['username']=usrname
return render(request, "Third.html",dic)
if 'ThirdPageSub' in request.POST:
usrname = request.POST.get("usrnm", None)
dic={}
dic['username']=usrname
return render(request, "Forth.html",dic)
by default django gives you {{ request.user.username }} through out your templates. So you can call it on any templates
You aren't passing the usrnm in your post request with SUBMIT on your SecondPageSub

Django and MySQL save multiple data

I am trying to save multiple fields of data. I've also changed the database connection from the default sqlite3 to MySQL. And I don't know how to do this
Here's my views.py
def customerview(request):
if request.POST:
form = CustomerForm(request.POST)
if form.is_valid():
if form.save():
return redirect('sales')
else:
return redirect('index')
else:
return redirect('index')
else:
form = CustomerForm
return render(request, 'customer.html', {'form':form})
def salesview(request):
if request.POST:
form = SalesForm(request.POST)
if form.is_valid():
if form.save():
return redirect('index')
else:
return redirect('index')
else:
return redirect('index')
else:
form = SalesForm
data = Customer.objects.latest('id')
return render(request, 'sales.html', {'form':form, 'range':range(data.number_of_transactions)})
Here's my models.py
class Customer(models.Model):
customer_name = models.CharField(max_length=200)
number_of_transactions = models.IntegerField()
class Sales(models.Model):
product_type = models.CharField(max_length=100)
product_code = models.CharField(max_length=100)
product_size = models.CharField(max_length=100)
product_quantity = models.IntegerField()
Here's my brands.html
<form class="form" role="form" action="" method="post"> {% csrf_token %}
{% for i in range %}
<div class="col">
<div class="col-sm-3">
<div class="">
{{ form.product_type | add_class:'form-control' }}
<label for="regular2">Product Type</label>
</div>
</div>
<div class="col-sm-3">
<div class="">
{{ form.product_code | add_class:'form-control' }}
<label for="regular2">Product Code</label>
</div>
</div>
</div>
{% endfor %}
<div class="col-md-12">
<hr>
<div class="card-actionbar-row">
<input type="submit" class="btn btn-flat btn-primary ink-reaction" value="SUBMIT">
</div>
</div>
</form>
The idea is to get the customer details and number of transactions to be performed then that determines the number of fields to be displayed in the sales view. And that works fine.
The problem is to get each of the transactions to be saved in the database. When I submit and check my database tables, only one transaction is saved.
It's clear that you're trying to run before you can walk here.
Firstly, you should concentrate on getting a simple list view to work, without getting confused about the additional complexity involved in displaying a list in a form view. So, make your view inherit from ListView, and remove all the methods. Then fix your template, so that it iterates over stock_list or object_list rather than just stock.
Secondly, once you've got that working, you could try to integrate it with a form. When you do that, learn what methods to override. get_queryset must return a queryset, it should not render a template. In any case, you should almost never need to render a template manually in a class-based view, because the existing logic will do that for you. And if you want to add a queryset to the template context in a create view, for example, you should be overriding get_context_data; which needs to return a dictionary.
Thirdly, if at some point you do need to render a template manually, read the documentation to learn the order of parameters to render: it is request, template_name, context, not as you have it.

Validate Form Based on Hidden Input's Template Value - Is It Possible?

I have a form that in layman's terms, has a bunch of buttons (that act like checkboxes) with values. Users can select a handful of buttons.
The buttons push their values (via a JQuery function) into a hidden input which I'm using to gather the values.
I would like to make sure that the "values=" attribute of each hidden input isn't null or "" when the user presses the submit form.
Ex: Make sure that the input does NOT equal this:
<input autocomplete="off" id="id_valuePlatform" name="valuePlatform" type="hidden"> or
<input autocomplete="off" id="id_valuePlatform" name="valuePlatform" type="hidden" value="">
Here's the forms.py:
class getGames(forms.Form):
valuePlatform = forms.CharField(required=True, error_messages={'required': 'You need to tell us your platform(s)!'}, widget=forms.HiddenInput(attrs={'autocomplete': 'off'}))
Template:
<form method= "POST" autocomplete="off"> {% csrf_token %}
{{ form.non_field_errors }}
<div class="container">
{% if form.valuePlatform.errors %}
<ol>
{% for error in form.valuePlatform.errors %}
<li><strong>{{ error|escape }}</strong></li>
{% endfor %}
</ol>
{% endif %}
</div>
{{ form.valuePlatform }}
</div>
</div>
</form>
Views.py:
from .forms import getGames
def find(request):
form = getGames()
context = {"form": form}
if form.is_valid():
print form.cleaned_data['valuePlatform']
Is this even possible, or would I have to pass the data to Django via a Ajax POST?
Changed views.py to this, after looking at # Alasdair's examples in the documentation:
from .forms import getGames
def find(request):
form = getGames(request.POST or None)
context = {"form": form}
if request.method == 'POST':
if form.is_valid():
print form.cleaned_data['valuePlatform']

Django edit template for ModelForm is not being filled in with values

I have a ModelForm that I have created a view and template with to add an instance to the database. I am now trying to extend this to be editable when the user clicks a button - but when they do that the form/template page appears and I get the "This Field is required message" but all fields are empty instead of pre-populated with the instance I passed in, but when I edit the values to something different than originally then in my database the correct instance is updated. So it is passing the primary key but none of the values are showing up. If anyone can tell what I am doing wrong I would appreciate it, oh, and I am using this post Django edit form based on add form? as a basis so please don't just send me there.
Here are my files
ModelForm
class CreditCardForm(forms.ModelForm):
class Meta:
model = CreditCard
fields = ('name_on_card','card_number','contact_number_on_card')
View
def edit(request, id=None, template_name='article_edit_template.html'):
if id:
print "Edit Mode"
card = get_object_or_404(CreditCard, pk=id)
if card.card_owner != request.user:
raise HttpResponseForbidden()
else:
print "Create Mode"
card = CreditCard(card_owner=request.user)
if request.POST:
print "request.POST"
form = CreditCardForm(request.POST, instance=card)
if form.is_valid():
print "is_valid()"
form.save()
# If the save was successful, redirect to another page
# redirect_url = reverse(article_save_success)
return HttpResponseRedirect('/cards/')
else:
print "else"
form = CreditCardForm(instance=card)
return render_to_response(
'create_credit.html',
{'form': form,},
context_instance=RequestContext(request)
)
Template
{% include "base.html" %}
<form action="" method="post">{% csrf_token %}
<fieldset>
<legend>Required</legend>
<div class="fieldWrapper">
{{ form.name_on_card.errors }}
<label for="id_topic">Name as it appears on card:</label>
{{ form.name_on_card }}
</div>
<div class="fieldWrapper">
{{ form.card_number.errors }}
<label for="id_topic">Last 6 digits of card number:</label>
{{ form.card_number }}
</div>
</fieldset>
<fieldset>
<legend>Optional</legend>
<!-- This is for Credit Card's Only -->
<div class="fieldWrapper">
{{ form.contact_number_on_card.errors }}
<label for="id_topic">Institution contact number: 1-</label>
{{ form.contact_number_on_card }}
</div>
</fieldset>
<p><input type="submit" value="Save"></p>
</form>
URLS
url(r'^new/credit/$', views.edit, {}, 'crds_newCredit'),
url(r'^edit/credit/(?P<id>\d+)/$', views.edit, {}, 'crds_editCredit'),
#xizor use a link instead a button to redirect to the edition form, becasue with the button you are probably sending a post to the view.
PS: Please forgive my English, edit this answer if you think it is right to make it more useful.

Categories