Flask validate and upload file to web page to - html

I've been attempting to upload and use a file to my web page but continually run into errors. I have searched repeatedly and tried many different solutions with no success. Any direction would be appreciated.
/app/forms.py
class UploadForm(FlaskForm):
cadfile = FileField('cadfile', validators=[FileRequired(), FileAllowed(['STEP','STP'], 'Step Files Only')])
upload = SubmitField('Upload')
def __init__(self, *args, **kwargs):
super(UploadForm, self).__init__(*args, **kwargs)
self.user = None
def validate(self):
initial_validation = super(UploadForm, self).validate()
if not initial_validation:
print('Fails')
return False
return True
This part of the code fails everytime at "not initial_validation", regardless of no file, incorrect file type or correct file type.
/app/routes.py
#app.route('/index', methods=['GET', 'POST'])
def index():
form = UploadForm()
if form.validate_on_submit():
if 'cadfile' in request.files:
cadfile = request.files['cadfile']
cadfile.save('/app/tmp/' + cadfile.filename)
print('Success')
else:
print('No Go')
return redirect(url_for('details'))
return render_template('index.html', title='Home', form=form)
And my html file
/app/templates/index.html
<html>
<head>
<title>Upload</title>
</head>
<body>
<h1>Let's Do This</h1>
<form method="post" enctype="multipart/form-data">
{{ form.hidden_tag() }}
{{ form.cadfile }}
{{ form.upload() }}
</form>
</body>
</html>
I would like to have it print out 'No File' when no file is selected, 'Invalid File Type' when not a STP or STEP file, and 'Success' when file is successfully uploaded.

Got it working. Here is my final code
/app/forms.py
class UploadForm(FlaskForm):
print('called uploadform')
cadfile = FileField('cadfile', validators=[FileRequired()])
upload = SubmitField('Upload')
/app/routes.py
def index():
form = UploadForm()
FILE_TYPES = set(['STEP'])
var.company_id = current_user.company_id
if form.validate_on_submit():
print('Validated')
submit_name = form.cadfile.data.filename
if '.' in submit_name and submit_name.rsplit('.', 1)[1] in FILE_TYPES:
print('Yea Baby it is!')
...
code
...
return redirect(url_for('details'))
else:
form.cadfile.errors.append('File is not an accepted format')
return render_template('index.html', title='Home', form=form)
/app/templates/index.html
<form method="post" enctype="multipart/form-data">
{{ form.hidden_tag() }}
<p>
{{ form.cadfile }}
{{ form.upload() }}<br>
{% for error in form.cadfile.errors %}
<span style="color: red;">[{{ error }}]</span>
{% endfor %}
</p>
</form>
</body>
Thanks

Related

facing problems in uploading files to a particular directory

i am using a html template to upload a file but i don't know how to process that file in django views file
i also have a model which is connected with the database
here is my html file
{% extends 'base.html' %}
{% block body %}
<form action="file" method="post" enctype="multipart/form-data" >
{% csrf_token %}
<input type="text" name="userName" placeholder="username">
<input name="file" type="file">
<input type="submit" value="submit">
</form>
{% for message in messages %}
{{ message }}
{%endfor%}
{% endblock %}
and here is my views.py function
def File(request):
if request.user.is_authenticated:
if request.method == 'POST':
user = request.POST['userName']
file = request.FILES
print(file)
# file = request.POST.copy()
# file.update(request.FILES)
# content_type = copied_data['file'].get('content-type')
# path = os.path.join(r'C:\Users\harsh\PycharmProjects\swatchBharat\SwatchBharat\media\files\\',file)
if User.objects.filter(username=user).exists():
file2 = points()
file_obj1 = DjangoFile(open(file, mode='rb'), name=file)
file_obj = File.objects.create(title=file, file=file_obj1, content_object=file, author=file.client)
file2.file =file2.save(ContentFile(file_obj))
file2.user = user
file2.save()
return HttpResponse('sucess bale bale!!!!!!!')
else:
messages.info(request,'the username you entered is incorrect')
return redirect("file")
return render(request, 'file.html')
else:
return HttpResponse('sorry this is restricted, login to continue')
my model.py file
from django.db import models
# Create your models here.
class points(models.Model):
user = models.TextField(max_length=50,default=None)
file = models.FileField(upload_to='files/')
point_3 = models.BooleanField(default=False)
point_5 = models.BooleanField(default=False)
point_9 = models.BooleanField(default=False)
i am stuck with it pls someone help me out
the solution for this is simple , thanks to shivendra-pratap-kushwaha for documentation link - docs.djangoproject.com/en/3.2/topics/http/file-uploads this was really helpfull
just need to specify request.FILES['file'] instead of request.FILES

form fields a not showing up on html page django

This is my template which I am using in the login page but the problem is fields are not showing up .I want to use mdbootstrap on the page.i have searched it on many websites but did't got a solution and every one was using the same thing to use the form is the something I am missing in my code?
<form action="{% url 'log_in' %}" method="POST">
{% csrf_token %}
<div class="md-form">
<i class="fa fa-envelope prefix"></i>
{{ form.username }}
{{ form.username.label_tag }}
</div>
<div style="padding:5px"></div>
<div class="md-form" >
<i class="fa fa-lock prefix"></i>
{{ form.password.label_tag }}
{{ form.password }}
</div>
{% if requset.GET.next %}
<input type="hidden" name="next" value="{{ request.GET.next }}">
{% endif %}
<button type='submit' class="btn info-color ">log in</button>
</form>
and forms.py
from django.contrib.auth.forms import AuthenticationForm
from django import forms
class LoginForm(AuthenticationForm):
username = forms.CharField(label="Username", max_length=30,
widget=forms.TextInput(attrs={'class': 'form-control', 'name': 'username'}))
password = forms.CharField(label="Password", max_length=30,
widget=forms.PasswordInput(attrs={'class': 'form-control', 'name': 'password'}))
my view function is
def log_in(request):
if request.user.is_authenticated:
return render(request,'registration/userhome.html')
elif request.POST:
username = request.POST['username']
password = request.POST['password']
user = authenticate(request, username=username, password=password)
if user.is_active:
login(request, user)
return render(request,"registration/userhome.html")
else :
return HttpResponse("Invalid login details supplied.")
views login_view()
def login_view(request):
if request.method == 'POST':
form = LoginForm(request.POST)
if form.is_valid():
pass # does nothing, just trigger the validation
else:
form = LoginForm()
return render(request,"registration/login.html",{'form':form})
I have not even rendered the login page but still they are working and the part of form feilds are missing in it
my urls.py file
from django.urls import path
from . import views
from django.contrib.auth.views import LoginView
urlpatterns =[
path("",views.index,name='index'),
path("userhome/",views.userhome,name='userhome'),
path("quiz/", views.quiz, name='quiz'),
path("signup/", views.sign_up,name='sign_up'),
path("login/", views.login_view, name='login'),
path("login/", views.log_in, name='log_in'),
path("index", views.log_out,name='log_out'),
path("rules/",views.rules,name='rules'),
]
You must have a view like this :
def myView(request):
if request.method == 'POST':
form = LoginForm(request.POST)
if form.is_valid():
pass # does nothing, just trigger the validation
else:
form = LoginForm()
return render(request, 'myTemplate.html', {'form': form})

Django how to adding comments option on a post

I am developing a blog which i want to add comment form option to it, i have added the form to the same page directly under the article, i want that went a user comment it should redirect to the same page with the article but i keep getting and error
here is my code
view
def comment(request, article_id):
try:
article = Article.objects.get(pk=article_id)
if request.method == 'POST':
form = CommentForm(request.POST)
if form.is_valid():
comment = form.cleaned_data['comment']
article.comments_set.create(comment=comment)
#messages.infos(request,comment)
return redirect('blog:_article')
#else:
#pass
#form = CommentForm()
#context['form'] = form
#return render(request,'blog/comment.html', context)
except Exception as e:
#wriet error to file
return render(request,'blog/404.html')
urls
from django.urls import path
from . import views
app_name = 'blog'
urlpatterns = [
path('', views.index, name='index'),
path('<int:article_id>/article', views._article, name='_article'),
path('<int:article_id>/comment', views.comment, name='comment'),
]
models
class Comments(models.Model):
comment = models.TextField()
date = models.DateTimeField(default=timezone.now)
article = models.ForeignKey(Article, on_delete=models.CASCADE)
def __str__(self):
return self.comment
form
<form method="post" action="{% url 'blog:comment' article.id %}">
{% csrf_token %}
{% for field in form %}
{{ field.label_tag }}
{% render_field field class="form-control is-valid" rows="4" %}
{% endfor %}<br>
<button class="btn btn-success">Post</button>
</form>
I finally did it by adding the code to handle the comment in the same view that renders the articles this is my code
def _article(request, article_id):
try:
article = Article.objects.get(pk=article_id)
related_articles = Article.objects.filter(tags=article.tags).exclude(pk=article.pk)[:4]
context['article'] = article
context['related_articles'] = related_articles
context['form'] = CommentForm()
if request.method == 'POST':
form = CommentForm(request.POST)
if form.is_valid():
comment = form.cleaned_data['comment']
article.comments_set.create(comment=comment)
return render(request,'blog/article.html', context)
except Exception as e:
#write error to file
return render(request,'blog/404.html')
If you don't want the page to redirect to another page or update the page, you should use AJAX (https://www.w3schools.com/jquery/jquery_ajax_get_post.asp) in this case. Your form will hit the url in the action by changing your page to that url so you have to handle the redirecting and rendering in your commenting view to come back to same page if you don't wanna do this dynamically.

how to get the data from view to templates?

i'm trying to get the data from my views.py to the html page.
if the views.py code is this
def VerifiedBySuperuser(request):
if request.method == 'POST':
vbs = MaanyaIT_EXAM48_ManageQuestionBank()
vbs.QuestionID = MaanyaIT_EXAM48_ManageQuestionBank.objects.get(QuestionID=request.POST.get(QuestionID, None))
vbs.QuestionInEnglishLang = request.POST.get('QuestionInEnglishLang', None)
vbs.save()
else:
return render(request, 'exam48app/verifiedbysuperuser.html')
then what shoud the code of html page to view my all data to the tamplates..
this is my html page
<form class="from-horizontal" method="post" enctype="multipart/form-data">
{% csrf_token %}
<div class="post-entry">
{{ MaanyaIT_EXAM48_ManageQuestionBank.QuestionInEnglishLang }}
</div>
</form>
now what should i do?
From your comment, you need to know How to write/render the data from view to html template
I will demonstrate a simple example for you,
Assuming you have a view as below,
def VerifiedBySuperuser(request):
if request.method == 'GET':
context = {
"T_Name": "My Name",
"T_Age": 50,
"T_Phone": 1478523699
}
return render(request, 'verifiedbysuperuser.html', context=context)
and a HTML template as follows,
<!DOCTYPE>
<html>
<body>
Name : {{ T_Name }}<br>
Age : {{ T_Age }}<br>
Phone : {{ T_Phone }}<br>
</body>
</html>
When you access your view, you will get a response like this,
In your case, you can pass as many attributes to template as dict (shown in my example) and in template/html keys of context (that is T_Name,T_Name etct) becomes variable. So you can directly use them in HTML inside the twin braces ({{ variable_name }})
As far as I knew, this is the general procedure for template rendering/ html rendering
UPDATE-1
def VerifiedBySuperuser(request):
if request.method == 'POST':
obj = MyModel.objects.get(id=some_id)
other_data = [1,2,3,4,] # some specific data
context = {
"post_data": request.data,
"object_instance": obj,
"some_other_data": other_data
}
return render(request, 'verifiedbysuperuser.html', context=context)

Uploading A file in django with ModelForms

I have been hacking away at this project for many hours now and just cannot figure out how to create a simple file upload app. I have looked at all the tutorials but none quite apply to my situation and i just cant get the code right. I know the code I have at this point wont run but I was hoping somone might be able to push me in the right direction with what I have. I know its not great but Im getting frustrated and I hope someone could help especially with my views.py Thank you so much. Thank you in advance!
Models.py
from django.db import models
from django.contrib.auth.models import User
from django.forms import ModelForm
class WorkSheet(models.Model):
worksheet_name = models.CharField(max_length= 150, default = True)
creator = models.ForeignKey(User, default = True)
worksheet_file = models.FileField(upload_to = 'worksheets', default = True)
number_of_stars = models.PositiveIntegerField(default = True)
category = models.CharField(max_length = 100, default = 0)
class UploadWorkSheetForm(ModelForm):
class Meta:
model = WorkSheet
Views.py
from django.shortcuts import render, render_to_response, HttpResponseRedirect
from django.conf import settings
from django import http
from models import WorkSheet
from forms import UploadWorkSheetForm
def upload(request):
template = 'upload.html'
if request.method == 'POST':
if 'file' in request.FILES:
file = request.FILES['file']
filename = file['filename']
fd = open('%s/%s' % (settings.MEDIA_ROOT, filename), 'wb')
fd.write(file['content'])
fd.close()
return http.HttpResponseRedirect('upload_success.html')
else:
form = UploadWorkSheetForm()
return render_to_response(template, {'form': form})
return render(request, 'upload.html', {'form': form})
Upload.html
<!DOCTYPE html>
<html>
<head>
<title>WSD Upload</title>
</head>
<body>
<h1>Upload WorkSheet</h1>
{% block body %}
<form action="." method="post" enctype="multipart/form-data"> {{ form }}
<type="submit" value = "Upload"/>
</form>
{% endblock %}
</body>
</html>
If there is anything else you need please tell me. Thank you thank you thank you!
views.py
def upload(request):
template = 'upload.html'
if request.method == 'POST':
form = UploadWorkSheetForm(request.POST, request.FILES)
if form.is_valid():
form.save()
return HttpResponseRedirect('upload_success.html') <---change this to your valid url not template name
else:
form = UploadWorkSheetForm()
return render(request, 'upload.html', {'form': form})
template
...................
{% block body %}
<form action="." method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value = "Upload"/>
</form>
{% endblock %}
....................