django form to upload file returns error as form not valid - forms

I am developing an app in Django.
My users are allowed to save data by compiling a form like this
Tool:
acronym:
definition:
defined by the following function, in forms.py:
class tool_form(forms.ModelForm):
class Meta:
model=tool
fields=["Tool", "Acronym", "Definition"]
That saves the data into a model like this:
class tool(models.Model):
Tool = models.CharField(max_length=256, blank=True, null=True)
Acronym = models.CharField(max_length=25, blank=True, null=True)
Definition = models.TextField(blank=True, null=True)
The view function allowing this, is:
def add_tool(request):
if request.method=='POST':
form = tool_form(request.POST or None)
if form.is_valid():
form.save()
messages.success(request, ("Submit succeed!"))
return redirect('adding_tools')
else:
messages.error(request, ('ERROR: submit failed'))
return render(request, 'adding_tools.html', {})
else:
return render(request, 'adding_tools.html', {})
Now I want my users to be able to copile many times of the same form, all at once.
In order to achieve this, I am allowing my users to upload a file copiled with the data to insert.
So I am allowing my users to download a template xlsx file with colums with given name
Column 1 name (cell A1): Tool
Column 2 name (cell B1): acronym
Column 3 name (cell C1): definition
To compile it, inserting many records, and then to upload it back.
So I want my code to save this data into the same model declared before (tool)
I am trying to achieve this by:
in template add_tool_sheet.html:
<form class="container" method="POST" enctype="multipart/form-data" >
{% csrf_token %}
<div class="file-upload-wrapper" id="input-file-now">
<small id="inputHelp" class="form-text text-muted">Select file to upload.</small>
<input type="file" name="uploaded_file" id="input-file-now" data-max-file-size="5M" class="file-upload">
<br><br>
<div class="form-group">
<input name="Date" type="hidden" class="form-control" id="date_to_turn_into_toda">
</div>
<button type="submit" class="btn btn-primary">Upload</button>
</div>
</form>
in forms.py:
class tool_file_form(forms.ModelForm):
class Meta:
model=tool_file
fields=["Tool_file", "Date"]
In models.py
class tool_file(models.Model):
Tool_file = models.FileField(upload_to='uploaded_sheets/', blank=False, null=False)
Date = models.DateField(blank=False, null=False, default=timezone.now().date() )
class Meta:
ordering = ['Date', 'Tool_file']
def clean(self):
if not (self.Tool_file or self.Date):
raise ValidationError("something went wrong")
def __str__(self):
return "%s ----- [%s]" % (self.Tool_file, self.Date)
in views.py:
def add_tool_sheet(request):
if request.method=='POST':
form = tool_file_form(request.POST, request.FILES)
if form.is_valid():
form.save()
messages.success(request, ("upload succeeded"))
return redirect('add_tool_sheet')
else:
messages.error(request, ('ERROR n1'))
return render(request, 'add_tool_sheet.html', {})
else:
return render(request, 'add_tool_sheet.html', {})
When I try to add new objects in the model tool_file from admin section, it works.
But when I try to add new objects from the user interface (template add_tool_sheet.html), it returns
ERROR n1
as message, and my console returns
GET /admin/ HTTP/1.1" 200 7381
Why?
Please note:
The upload from admin section works, the upload from user interface does not.

SOLVED
In template I put
name="uploaded_file"
but in order to match with the information in forms.py and model.py, it has to be:
name="Tool_file"
Now it works!

Related

Django2 forms nothing happend when submit post article

I have forms to Post Article in my blog Django2. When I run django server there is no error, but when I Post and submit Article in my frontEnd apps nothing happens and doesn't save any data.
Any help on this would be highly appreciated!
Template HTML
<div class="create-article">
<h2>Create an Awesome New Articles</h2>
<form class="site-form" action="{% url 'articles:create' %}" method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{ form }}
<input type="submit" value="Create">
</form>
</div>
forms.py
from django import forms
from . import models
class CreateArticle(forms.ModelForm):
class Meta:
model = models.Article
fields = ['title', 'body', 'slug', 'thumb']
views.py
def article_create(request):
if request.method == 'POST':
form = forms.CreateArticle(request.POST, request.FILES)
if form.is_valid():
# save article to db
instance = form.save(commit=False)
instance.author = request.user
instance.save
return redirect('articles:list')
else:
form = forms.CreateArticle()
return render(request, 'articles/article_create.html', {'form': form})
urls.py
from django.urls import path
from . import views
app_name = 'articles'
urlpatterns = [
path('', views.article_list, name="list"),
path('create/', views.article_create, name="create"),
path('<slug>/', views.article_detail, name="detail"),
]
Thanks.
It starts here: instance = form.save(commit=False), where you are not commiting the save.
Further down you have instance.save as if you were setting a model field, but with not value given to it.
Make that line instance.save() instead.

REACT Multiple Registration

I have a problem with React, so I created script and it doesn't work.
This should:
Render first state step (it's working) (Component First)
Here is error, it don't see default values.(name & email
After click Save And Continue it should save files to data.
And going to next steps in cases.
The error is
bundle.js:34147 Uncaught ReferenceError: email is not defined
function send(e){
e.preventDefault()
}
function nextStep(){
this.setState({
step:this.state.step + 1
})
}
function nextStep(){
this.setState({
step:this.state.step - 1
})
}
function saveAndContinue(e) {
e.preventDefault()
// Get values via this.refs
var data = {
name : this.refs.name.getDOMNode().value,
email : this.refs.email.getDOMNode().value,
}
this.props.saveValues(data)
this.props.nextStep()
};
var fieldValues = [
name : null,
email : null,
];
function saveValues(fields) {
return (
fieldValues = Object.assign({}, fieldValues, fields)
);
}
class Registration extends React.Component{
constructor () {
super()
this.state = {
step:1
}
}
render() {
switch (this.state.step) {
case 1:
return <First fieldValues={fieldValues}
nextStep={this.nextStep}
previousStep={this.previousStep}
saveValues={this.saveValues} />
case 2:
return <Two fieldValues={fieldValues}
nextStep={this.nextStep}
previousStep={this.previousStep}
saveValues={this.saveValues}/>
case 3:
return <Third fieldValues={fieldValues}
nextStep={this.nextStep}
previousStep={this.previousStep}
saveValues={this.saveValues}/>
case 4:
return <Success fieldValues={fieldValues} />
}
}
}
class First extends React.Component{
render(){
return(
<form onSubmit ={send}>
<div className="group">
<input className="text" type="text" ref="name" defaultValue={this.props.fieldValues.name}/>
<span className="highlight"></span>
<span className="bar"></span>
<label>Write Name</label>
</div>
<div className="group">
<input className="text" type="email" ref="email" defaultValue={this.props.fieldValues.email} />
<span className="highlight"></span>
<span className="bar"></span>
<label>Write Your Mail</label>
</div>
<button onClick={this.saveAndContinue}>Save and Continue</button>
</form>
)
}
}
There is no Two, Third and Success classes in your code, so I'm assuming they are similar to the First class.
A global function doesn't need this keyword. But in this case, you have to put saveAndContinue inside First class if it need to access the state.
In React, normally you don't have to set default value for input.
Link the input value to the state, and then setState in onChange event.
The string in placeholder is shown when the state is empty.
The code below shows how to work with input tag in React:
<input
value={this.state.inputValue}
onChange={e => {
this.setState({ inputValue: e.target.value });
}}
type="text"
placeholder="default value"
/>
Note that the state will updates onChange rather than click the save button.
Does this solve your problem?

Shrine with Rails multiple polymorphic image uploads

I've been struggling for about 5 hours trying to understand why Shrine is blocking my uploads. I either get errors like "Shrine: Invalid file", or "Expected Array but got string" in strong params. If there aren't errors, the images aren't actually saved.
require "image_processing/mini_magick"
class ImageUploader < Shrine
include ImageProcessing::MiniMagick
plugin :activerecord
plugin :backgrounding
plugin :cached_attachment_data
plugin :determine_mime_type
plugin :delete_raw
plugin :direct_upload
plugin :logging, logger: Rails.logger
plugin :processing
plugin :remove_attachment
plugin :store_dimensions
plugin :validation_helpers
plugin :versions
Attacher.validate do
validate_max_size 2.megabytes, message: 'is too large (max is 2 MB)'
validate_mime_type_inclusion ['image/jpg', 'image/jpeg', 'image/png', 'image/gif']
end
def process(io, context)
case context[:phase]
when :store
thumb = resize_to_limit!(io.download, 200, 200)
{ original: io, thumb: thumb }
end
end
end
class Image < ActiveRecord::Base
include ImageUploader[:image]
belongs_to :imageable, polymorphic: true
end
class Product < ApplicationRecord
has_many :images, as: :imageable, dependent: :destroy
accepts_nested_attributes_for :images, allow_destroy: true
...
# Strong Params:
def product_params
params.require(:product).permit(
:name, :brand_id, :category_id, :price, :compare_price, :description,
images_attributes: { image: [] },
product_properties_attributes: [:id, :property_id, :value]
)
...
And my view:
<%= f.fields_for :images do |image_form| %>
<%= image_form.file_field :image, multiple: true %>
<% end %>
According to everything I've read on the docs or from gorails, this should work. Do I need to restructure the images_attributes hash? I also tried using direct_uploads, but struggled to get the presigned_url to work with S3.
Refile makes this really easy, so I'll probably run crying back to that.
Is there something I'm obviously doing wrong?
According to the fields_for documentation, the provided block will be called for each image in the project.images collection. So if your product currently doesn't have any images, the block won't be called (according to the docs).
For nested attributes to work, you need to forward the following parameters when creating the Product:
product[images_attributes][0][image] = <file object or data hash>
product[images_attributes][1][image] = <file object or data hash>
product[images_attributes][2][image] = <file object or data hash>
...
If you look at the "Multiple Files" Shrine guide, it's recommended that you just have a single file field which accepts multiple files:
<input type="file" name="file" multiple>
And then setup direct uploads for this field using Uppy, dynamically generating the image field for each uploaded file populated with the uploaded file data hash:
<input type="hidden" name="product[images_attributes][0][image]" value='{"id":"...","storage":"cache","metadata":{...}}'>
<input type="hidden" name="product[images_attributes][1][image]" value='{"id":"...","storage":"cache","metadata":{...}}'>
....
Alternatively you can just let users attach multiple files, which are all submitted to the app, and then destructure them in the controller:
class ProductsController < ApplicationController
def create
images_attributes = params["files"].map { |file| {image: file} }
Product.create(product_params.merge(images_attributes: images_attributes))
end
end
In that case you have to make sure your HTML form has the enctype="multipart/form-data" attribute set (otherwise only the files' filenames will get submitted, not files themselves).

"TypeError: filter_by()" error returned in flask when I am trying to use filter_by()

I am trying to implement filter_by() function of flask. My issue is, when I am trying to use filter for argument, I got the error of:
TypeError: filter_by() takes 1 positional argument but 2 were given
I also attached my code to the question.
Main application source code:
def login():
error = None
form = LoginForm(request.form)
if request.method == 'POST':
user = User.query.filter_by(Email=request.form['email']).first()
password = User.query.filter_by(Password=request.form['password']).first()
group = User.query.filter_by(user).first()
if user is None or password is None :
session['logged_in'] = False
flash('Please write your username password')
else:
session['logged_in'] = True
flash('You were logged in')
if group=="viewer":
return redirect(url_for('viewer'))
elif group=="admin":
return redirect(url_for('admin'))
elif group=="employee":
return redirect(url_for('employee'))
return render_template('login.html', form=form)
The model which I used for my app :
class User(db.Model):
__tablename__ = 'users'
Id = db.Column(db.Integer, primary_key=True)
Name = db.Column(db.String(64), index=True, unique=True)
Email = db.Column(db.String(64), index=True, unique=True)
Password = db.Column(db.String(128), index=True )
Group = db.Column(db.String(30))
Tickets = db.relationship('Request', backref='author', lazy='dynamic')
Login page source code:
<div class="innter-form">
<form class="sa-innate-form" method="post">
{{ form.csrf_token }}
<label>Email Address</label>
<input type="text" name="email" value="{{ request.form.email }}">
<label>Password</label>
<input type="password" name="password" value="{{ request.form.password }}">
<button type="submit" value="submit">Sign In</button>
Forgot Password?
</form>
</div>
filter_by is used for queries on the column names
...
# this returns a user object
user = User.query.filter_by(Email=request.form['email']).first()
# you should query based on the Id of User
group = User.query.filter_by(Id=user.Id).first()
Probably the problem is in the line
group = User.query.filter_by(user).first()
Besides the fact that filter_by accepts only keyword arguments - and you supplied only one positional argument to it, I am guessing you should use something different than User here (maybe Group, not sure since I don't know what models you have defined).
The line I mentioned should look something like
group = Group.query.filter_by(user=user).first()
Thank you all for response:
The eror was in group part as mention in above:
group = User.query.filter_by(user).first()
Instead of this code should be:
group = User.query.filter_by(Email=user).first()

error 405 web.py

I got an error 405 as you can read, here is my code and my guess of what's wrong. The code is pretty basic, they are 3 files, main.py, blog.py, and form.html. As additional info: this code uses sessions, a subapp, and templates.
main.py --
import web
import blog
urls = (
"/blog", blog.app_blog,
"/(.*)", "index"
)
web.config.debug = False
app = web.application(urls, locals())
session = web.session.Session(app, web.session.DiskStore('sessions'))
render = web.template.render('views/', globals = {'session': session})
class index:
def GET(self, path):
session.names = ''
session.surnames = ''
session.nin = ''
session.address = ''
session.phone = ''
session.email = ''
return render.form()
if __name__ == "__main__":
app.run()
--
blog.py --
import web
urls = (
"", "reblog",
"/", "blog"
)
class reblog:
def GET(self): raise web.seeother('/')
class blog:
def GET(self):
return "getblog"
def POST(self):
return "postblog"
app_blog = web.application(urls, locals())
-- form.html--
<form method=post action=blog>
<ul>
<li><input name=names required maxlength=24 placeholder="Name" value="$session.names"></li>
<li><input name=surnames required maxlength=24 placeholder="Surname" value="$session.surnames"></li>
<li><input name=nin requiered maxlength=12 placeholder="RUT" value="$session.nin"></li>
<li><input name=address required maxlenght=64 placeholder="Address" value="$session.address"></li>
<li><input name=phone required maxlength=10 placeholder="Phone" value=$session.phone></li>
<li><input name=email type=email required maxlenght=254 placeholder="email" value=$session.email></li>
<li><input name=password type=password required placeholder="password"></li>
<li><input name=confirmpassword type=password required placeholder="Confirmar pass"></li>
<li><input type=submit value="registrarse"></li>
</ul>
The thing is that the user inputs are not use by the POST, rather it gives me an error 405 exactly like this:
"HTTP/1.1 POST /blog" - 405 Method Not Allowed
and the browser prints None.
Please give me a hand guys, this is pretty frustrating, if you know what I mean.
Thanks beforehand.
Cheers.
It happens because /blog url is mapped to class reblog that doesn't have POST method defined.