upload file to custom directory in django PYTHON - python

i have custom form for which i need to upload the image to some directory , below is the code
views function
def user_profile(request):
if request.method == 'POST':
form = ImageForm(request.POST, request.FILES)
if form.is_valid() and form.is_multipart():
new_user = save_file(request.FILES['image'])
return HttpResponse(new_user)
else:
form = ImageForm()
return render_to_response('user_profile.html', { 'form': form })
def save_file(file, path='home/ghrix/ghrixbidding/static/images/'):
''' Little helper to save a file
'''
filename = file._get_name()
fd = open('%s/%s' % (MEDIA_ROOT, str(path) + str(filename)), 'wb')
for chunk in file.chunks():
fd.write(chunk)
fd.close()
and below is the form:
<form method="POST" class="form-horizontal" id="updateform" name="updateform" enctype="multipart/form-data" action="/user_profile/">{% csrf_token %}
<input type="file" id="fileinput" name="fileinput" />
<button class="btn btn-gebo" type="submit">Save changes</button>
</form>
but am getting this error :
The view userprofile.views.user_profile didn't return an HttpResponse object.

The error says that your view is not returning any HttpResponse. There is one case that it's possible -
def user_profile(request):
if request.method == 'POST':
form = ImageForm(request.POST, request.FILES)
if form.is_valid() and form.is_multipart():
new_user = save_file(request.FILES['image'])
return HttpResponse(new_user)
# ------^
# There is not else check. It's possible that the if condition is False.
# In that case your view is returning nothing.
else:
form = ImageForm()
return render_to_response('user_profile.html', { 'form': form })

Regarding that error, the problem is in your view: if your form is invalid, you are not returning a response to the client:
def user_profile(request):
if request.method == 'POST':
form = ImageForm(request.POST, request.FILES)
if form.is_valid():
new_user = save_file(request.FILES['image'])
return HttpResponse(new_user)
else:
form = ImageForm()
# *** Unindented
return render_to_response('user_profile.html', { 'form': form })
also (I don't have much experience with file uploads) but I don't think you need the is_multipart check - it may be causing your form to appear invalid.

Related

Django ValueError (The view views.save_flow_data didn't return an HttpResponse object. It returned None instead.)

When I try to submit my form I get this message:
The view views.save_flow_data didn't return an HttpResponse object. It returned None instead.
Views.py
def save_flow_data(request):
if request.method == 'POST':
if request.POST.get('upload_flow') \
and request.POST.get('water_flow_rate')\
and request.POST.get('water_flow_rate_unit')\
data=CalcData()
data.water_flow_rate = request.POST.get('water_flow_rate')
data.water_flow_rate_unit = request.POST.get('water_flow_rate_unit')
data.save()
return render(request, 'io/flow.html')
else:
return render(request,'io/flow.html')
models.py
class CalcData(models.Model):
upload_flow = models.BooleanField(default=False)
water_flow_rate = models.DecimalField(max_digits=100, decimal_places=5)
water_flow_rate_unit = models.TextChoices('wfr_unit', 'm3/day m3/month')
datetime = models.DateTimeField(default=timezone.now)
submit button in form
<div>
<button action="{% url 'MyProject:save_flow_data' %}" type="submit" class="btn btn-light" style="width: 517.5px;" >Calculate</button>
</div>
urls.py
urlpatterns = [
path('', views.home, name='MyProject-home'),
path('io/flow/', views.io_flow, name='MyProject-io-flow'),
path('io/flow/save_flow_data', views.save_flow_data, name='save_flow_data')
]
I'm really not sure where to go from here. I had a perfectly working form but as soon as I scaled it up it flopped.
The case
if request.POST.get('upload_flow') \
and request.POST.get('water_flow_rate')\
and request.POST.get('water_flow_rate_unit')\
is False is not covered.
You need to either remove the last else :
def save_flow_data(request):
if request.method == 'POST':
if request.POST.get('upload_flow') \
and request.POST.get('water_flow_rate')\
and request.POST.get('water_flow_rate_unit')\
data=CalcData()
data.water_flow_rate = request.POST.get('water_flow_rate')
data.water_flow_rate_unit = request.POST.get('water_flow_rate_unit')
data.save()
return render(request, 'io/flow.html')
return render(request,'io/flow.html')
Or add a return to the uncovered path:
def save_flow_data(request):
if request.method == 'POST':
if request.POST.get('upload_flow') \
and request.POST.get('water_flow_rate')\
and request.POST.get('water_flow_rate_unit')\
data=CalcData()
data.water_flow_rate = request.POST.get('water_flow_rate')
data.water_flow_rate_unit = request.POST.get('water_flow_rate_unit')
data.save()
return render(request, 'io/flow.html')
return render(request, 'io/flow.html') # Or return something else
else:
return render(request,'io/flow.html')
Remove else statement and keep indentation of:
return render(request,'io/flow.html')
At function level.

Using data returned from forms in Django

Sorry for being a little new. My goal is to use the data collected from a user form to output a graph. The user inputs an initial 'price' then submits this number, it then goes into my formulas written in python and then django should display a chart in the same HTML file. I'm currently stuck on how to use data from 'POST'.
For example, if I'd like to take the cleaned_data from 'strike1' and multiply it by 4, then display it on the webpage, how would I go about doing that?
views.py
from django.shortcuts import render
from .forms import DataForm
# Create your views here.
def data(request):
if request.method == 'POST':
form = DataForm(request.POST)
if form.is_valid():
strike1 = form.cleaned_data['strike1']
strike2 = form.cleaned_data['strike2']
strike3 = form.cleaned_data['strike3']
strike4 = form.cleaned_data['strike4']
strategy = form.cleaned_data['strategy']
price = range(0,50)
premium1 = form.cleaned_data['premium1']
premium2 = form.cleaned_data['premium2']
premium3 = form.cleaned_data['premium3']
premium4 = form.cleaned_data['premium4']
contracts = form.cleaned_data['contracts']
form = DataForm()
return render(request, 'form.html', {'form': form})
forms.py
from django import forms
class DataForm(forms.Form):
strategy = forms.ChoiceField(
choices=[('Long Call', 'Long Call'), ('Long Put', 'Long Put'), ('Short Call', 'Short Call',),
('Short Put', 'Short Put'), ('Bull Call Spread', 'Bull Call Spread'),
('Bear Put Spread', 'Bear Put Spread'), ('Straddle', 'Straddle'),
('Butterfly Spread', 'Butterfly Spread'),
('Box Spread', 'Box Spread'), ('Iron Condor', 'Iron Condor')])
strike1 = forms.FloatField()
strike2 = forms.FloatField()
strike3 = forms.FloatField()
strike4 = forms.FloatField()
premium1 = forms.FloatField()
premium2 = forms.FloatField()
premium3 = forms.FloatField()
premium4 = forms.FloatField()
contracts = forms.IntegerField()
form.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Website</title>
</head>
<body>
<form method="'post">
{% csrf_token %}
{{ form }}
<button type="Submit">Generate</button>
</form>
</body>
</html>
I'd say the cleanest way to do it, is to build up a new "content" and render a new page in the POST processing section. For example:
from django.shortcuts import render
from .forms import DataForm
# Create your views here.
def data(request):
if request.method == 'POST':
form = DataForm(request.POST)
if form.is_valid():
# ... do you processing as it
return render(request, 'output.html', {'data': whatever})
form = DataForm()
return render(request, 'form.html', {'form': form})
You could also just let it call through to the original render function, but you'll need to include whatever information you want in the context like {"form: form} already is.
U need to create 2 views for using data.(basicly)
One for form, one for your formulas.
in urls.py
path('formpage/', views.formpage, name='form_view'),
path('result/', views.result, name='MY_calculator'),
in views.py
def formpage(request):
return render(request, '-----Template-----',)
def result(request):
x=request.GET.get('xval')
y=request.GET.get('yval')
result=x+y
return render(request, '-----Result Template----', {'result': result})
and form action for template. ("" instead of)
<form action="{% url 'MY_calculator' %}">
You can set initial values to your form and render them to the same template within the same URL.
Here is an example:
def data(request):
if request.method == 'POST':
form = DataForm(request.POST)
if form.is_valid():
strike1 = form.cleaned_data['strike1'] * 2
strike2 = form.cleaned_data['strike2'] * 3
# Set initials
# strike1 & strike2 new values will be rendered as default values
# in your form
form = DataForm(initial={'strike1': strike1, 'strike2': strike2})
return render(request, 'form.html', {'form': form})
form = DataForm()
return render(request, 'form.html', {'form': form})
Also, you must pay attention, in your template HTML you wrote "'post" instead of "post".

Performing two actions with one form in django

Here I am trying to perform two actions deleting or sending email to selected users.For sending emails a form will be required so I stored checked users in a session like this and after sending email i am removing all the users from session with session['users'].clear().It says sub and msg is required even if I provided .
What's wrong with this code?
Deleting the selected users working fine
def selected_users(request):
form = SendMailForm()
selected_users = get_user_model().objects.filter(id__in=request.POST.getlist('users'))
initial = {'users':[]}
session = request.session.get('users',initial)
if selected_users:
for user in selected_users:
if not user in session['users']:
session['users'].append(user.email)
print('hello1',session['users'])
if selected_users and request.method == 'POST' and 'delete_selected' in request.POST:
count = selected_users.count()
selected_users.delete()
messages.success(request, '{} users deleted.'.format(count))
return redirect('view_users')
elif request.method == 'POST' and 'mail_selected' in request.POST:
form = SendMailForm(request.POST or None)
config = EmailConfiguration.objects.order_by('-date').first()
backend = EmailBackend(host=config.email_host, port=config.email_port, username=config.email_host_user,
password=config.email_host_password, use_tls=config.email_use_tls)
if form.is_valid():
sub = form.cleaned_data['sub']
msg = form.cleaned_data['msg']
for email in session['users']:
email = EmailMessage(subject=sub, body=msg, from_email=config.email_host_user, to=[email],
connection=backend)
email.send()
# clearing users from session after email sends
session['users'].clear()
messages.success(request, 'Your mail sent.')
return redirect('view_users')
else:
print(form.errors)
return render(request, 'send_mail_selected.html', {'users': selected_users,'form':form,'session':session})
forms.py
class SendMailForm(forms.Form):
#to = forms.EmailField(required=False)
sub = forms.CharField(max_length=250)
msg = forms.CharField(widget=forms.Textarea)
template
<form method="POST" >
{% csrf_token %
{{form.as_p}}
<button type="submit" class="btn btn-primary" name="mail_selected">Send </button>
</form>

Passing Variable (View --> Template --> View)

Problem: I want to generate a random number, and ask the user to calculate the addition of these two. Then, I want to evaluate the number and see if the solution is correct.
My issue: I can do everything except the evaluation bit, as the values of the random numbers change!
HTML file:
<p> What is {{ a }} + {{ b }} ? </p>
<form action="{% url 'form_handle' %}" method="POST">{% csrf_token %}
{{form.as_p}}
<button type="submit">Submit</button>
</form>
FORM file:
class MyForm(forms.Form):
num1 = forms.CharField(max_length=20)
VIEW file:
def form_handle(request):
if request.method == 'POST':
form = MyForm(request.POST) # if post method then form will be validated
if form.is_valid():
cd = form.cleaned_data
num1 = cd.get('num1')
#num2 = cd.get('num2')
#result = cd.get('result')
if float(num1) == float(a + b):
# give HttpResponse only or render page you need to load on success
return HttpResponse("Good job!")
else:
# if sum not equal... then redirect to custom url/page
return HttpResponseRedirect('rr/') # mention redirect url in argument
else:
a = random.randrange(5,10);
b = random.randrange(10,20);
form = MyForm() # blank form object just to pass context if not post method
return render(request, "rr.html", {'form': form, 'a': a, 'b':b})
The error I get is "local variable 'a' referenced before assignment". I did try and change initialisation of a and b, and put the code right after the function declaration but that did not work either, as the function would compare the numbers (a + b) with another set of randomly generated numbers
Any help is much appreciated, or perhaps a new approach to this problem. Do note that I am a beginner in Python though
You can try to store a and b in session data:
def form_handle(request):
if request.method == 'POST':
form = MyForm(request.POST) # if post method then form will be validated
if form.is_valid():
cd = form.cleaned_data
num1 = cd.get('num1')
#num2 = cd.get('num2')
#result = cd.get('result')
a = request.session.get('a', 0)
b = request.session.get('b', 0)
if float(num1) == float(a + b):
# give HttpResponse only or render page you need to load on success
return HttpResponse("Good job!")
else:
# if sum not equal... then redirect to custom url/page
return HttpResponseRedirect('rr/') # mention redirect url in argument
else:
a = random.randrange(5,10);
b = random.randrange(10,20);
request.session['a'] = a
request.session['b'] = b
form = MyForm() # blank form object just to pass context if not post method
return render(request, "rr.html", {'form': form, 'a': a, 'b':b})

ModelForm For Registration HttpResponseError

First off, I know what the error means, I'm just confused on the configuration.
I'm getting an error of:
views.Registration didn't return an HttpResponse object
The issue is when I visit localhost/Register, I get the above error.
Q: If I want localhost/Register to show form from RegistrationForm() when it loads the register.html template within render() (at the bottom) when /Register is accessed. How do I do that? Do I need to create another view like /NewUser that I currently have specified? My thought was that render() was going to execute to show the template (with the form inside it) when viewing /Register
Code:
a view of:
def Registration(request):
RegForm = RegistrationForm(request.POST or None)
if request.method == 'POST':
if RegForm.is_valid():
clearUserName = RegForm.cleaned_data['userNm']
clearPass = RegForm.cleaned_data['userPass']
RegForm.save()
try:
return HttpResponseRedirect('/NewUser/?user=' + clearUserName)
except:
raise ValidationError('Invalid Request', code='300') ## [ TODO ]: add a custom error page here.
else:
RegForm = RegistrationForm()
return render(request, 'VA/reuse/register.html', {
'form': RegForm
})
You need to render something if the request is 'GET' instead of 'POST': ie.
def Registration(request):
RegForm = RegistrationForm(request.POST or None)
if request.method == 'POST':
if RegForm.is_valid():
clearUserName = RegForm.cleaned_data['userNm']
clearPass = RegForm.cleaned_data['userPass']
RegForm.save()
try:
return HttpResponseRedirect('/NewUser/?user=' + clearUserName)
except:
raise ValidationError('Invalid Request', code='300') ## [ TODO ]: add a custom error page here.
else:
RegForm = RegistrationForm()
return render(request, 'VA/reuse/register.html', {
'form': RegForm
})
else:
RegForm=RegistrationForm()
return render(request, 'template.html', {'formset': RegForm})
of course, you should change the context for your template, depending on whatever it is you need to render.
No, you should just move everything from the else onwards back one indentation level. Otherwise, nothing is returned if the request is not a POST.

Categories

Resources