I work in a postproduction company, we have our media files on a server. Through the site running on a second server, the user would point to a file, perform some operations (calculating checksums for example) and save the results in the database.
I'm looking for a "best practices" example on how to use FilePathField to get the size of a file. I've read tutorials and searched in the docs, but I'm having trouble putting the pieces together for my needs.
Some relevant code (EDIT: corrected the views, #1 and #3 are printed):
models.py
class AssetTest(models.Model):
file_path = models.FilePathField(path=r"", default="")
file_name = models.CharField(max_length=250, default="")
file_size = models.IntegerField(default=0)
def __str__(self):
return self.file_path
forms.py
class AssetTestForm(forms.ModelForm):
class Meta:
model = AssetTest
fields = ("file_name", "file_size")
views.py
def asset_select(request):
if request.method == 'POST':
print("1")
form = AssetTestForm(request.POST)
if form.is_valid():
print("2")
form.save(commit=False)
form.file_name = request.FILES['file'].name
form.file_size = request.FILES['file'].size
form.save()
return HttpResponseRedirect('/assetmanage/assets/')
print("3")
else:
print("4")
form = AssetTestForm()
return render(request, 'assetmanage/asset_select.html', {'form': form})
asset_select.html
{% extends "assetmanage/base.html" %}
{% block title %}Add Asset{% endblock %}
{% block body %}
<div class="container-fluid">
<div class="row">
<div class="col-sm-12 col-md-7">
<div class="panel panel-default">
<div class="panel-body">
<form class="form-horizontal" name="asset_select" action="/assetmanage/asset/test/" method="post" enctype="multipart/form-data">
{% csrf_token %}
<div class="form-group">
<label class="control-label col-sm-2">Select a file:</label>
<input type="file" name="asset_file">
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-success">Submit</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
In your FilePathField give the correct path name
FilePathField(path="/home/simon/",..)
cleaned_data of FilePathField will give you the exact path so using that to get the file name and file size of it...
form = AssetTestForm(request.POST)
if form.is_valid():
form.save(commit=False)
temp_file_obj = TemporaryFileUploadHandler(form.cleaned_data['file_path'])
form.instance.file_size = temp_file_obj.chunk_size
form.instance.file_name = form.cleaned_data['file_path'].split("/")[-1]
form.save()
Related
I am new at Django I want some helps. Basically,I want from users that they can select multiple images and save it, but I got like this and I don't know how to do it. I want to display the images and user can select one of them.
please help me.
models.py
class Images(models.Model):
product_image=models.ImageField(upload_to='media',null=True, blank=True)
def __str__(self):
return "{}".format (self.product_image)
class user_select(models.Model):
name = models.CharField(max_length=200, null=True, blank=True)
product_image=models.ForeignKey(Images, on_delete=models.CASCADE)
def __str__(self):
return "{}".format (self.name)
forms.py
class UserForm(forms.ModelForm):
class Meta:
model = user_select
fields = '__all__'
views.py
def home(request):
form = UserForm()
if request.method == 'POST':
form = UserForm(request.POST)
if form.is_valid():
form.save()
context = {'form':form}
return render(request, 'home.html', {'form':form})
home.html
{% extends 'base.html' %}
{% load crispy_forms_tags %}
{% block content %}
<div class="container mt-5">
<div class="row mt-5 mr-5">
<div class="col-md-8 mt-5">
<div class="card border border-secondary mt-5">
<div class="col-md-8 mt-5" align='center'>
<form method="POST" action="" >
{% csrf_token %}
<div class="col-md-8">
{{ form|crispy }}
</div>
</form>
<button type="submit" class="btn btn-success mt-5 mb-5">Place Order</button>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
enter image description here
I have the following form to create new clients on a database on Django and rendered using crispyforms. However, even thoug it is rendered correctly, it's not creating new entries.
models.py
class Client (models.Model):
def __str__(self):
return self.name + ' '+ self.surname
name = models.CharField(max_length=120)
surname = models.CharField(max_length=120, null=True)
phone = models.PositiveIntegerField(null=True)
mail = models.EmailField(null=True)
sport = models.TextField(blank=True, null=True)
gender_options=(
("F", "femenino"),
("M", "masculino"),
)
gender = models.CharField(max_length=120, null=True, choices=gender_options)
birth = models.DateField(null=True)
def get_absolute_url(self):
return reverse("clientes:cliente", kwargs={"client_id": self.id})
pass
forms.py
from django import forms
from .models import Client
class NewClientForm(forms.Form):
name = forms.CharField(label='Nombres')
surname = forms.CharField(label='Apellidos')
phone = forms.CharField(label='Teléfono')
mail = forms.EmailField(label='Correo electrónico')
gender = forms.ChoiceField(label='Género', choices= Client.gender_options)
birth = forms.DateField(label='Fecha de nacimiento', widget=forms.TextInput(attrs={
'id': "datepicker",
}))
sport = forms.CharField(label='Deportes')
views.py
def new_client_view(request):
new_client_form = NewClientForm()
if request.method == "POST":
new_client_form = NewClientForm(request.POST)
if new_client_form.is_valid():
Client.objects.create(**new_client_form.cleaned_data)
else:
print(new_client_form.errors)
context = {
"form": new_client_form
}
return render (request, 'clients/new-client.html', context)
html
{% extends 'base.html' %}
{% load bootstrap4 %}
{% load crispy_forms_tags %}
{% block content %}
<h1>Nuevo cliente</h1>
<section class="container">
<form action="." method="POST" class="form-floating mb-3"> {%csrf_token%}
<div class="form-row">
<div class="form-group col-md-6 mb-0">
{{ form.name|as_crispy_field }}
</div>
<div class="form-group col-md-6 mb-0">
{{ form.surname|as_crispy_field }}
</div>
<div class="form-group col-md-6 mb-0">
{{ form.phone|as_crispy_field }}
</div>
<div class="form-group col-md-6 mb-0">
{{ form.mail|as_crispy_field }}
</div>
<div class="form-group col-md-6 mb-0">
{{ form.sport|as_crispy_field }}
</div>
<div class="form-group col-md-6 mb-0">
{{ form.gender|as_crispy_field }}
</div>
<div class="form-group col-md-6 mb-0">
{{ form.birth|as_crispy_field }}
</div>
</div>
<input class="btn btn-primary" type="submit" name="Save">
</form>
</section>
{% endblock content %}
Form is correctly rendered, but when the form is sent, no new entry is created. I can't get why. For me everything should be working.
I tried replicating your project twice, both times I had no issue copying your code directly. It works fine for me. I set up a couple of print statements in the view:
from django.shortcuts import render
from .forms import NewClientForm
from .models import Client
# Create your views here.
def new_client_view(request):
new_client_form = NewClientForm()
print('request method: ', request.method)
if request.method == "POST":
new_client_form = NewClientForm(request.POST)
if new_client_form.is_valid():
Client.objects.create(**new_client_form.cleaned_data)
print('new client created')
else:
print(new_client_form.errors)
context = {
"form": new_client_form
}
return render (request, 'clients/new-client.html', context)
This is what I see on the new client form page:
This is what I see on the command line as I visit the page and submit the form:
As you can see, once I visit the page, the view receives a GET request, which makes sense, and which I see from your comment that you're seeing too. Once I hit "Submit" the view receives a POST request, which then creates a new Client object.
I used the Django shell to confirm that the Client object was indeed created:
So your code is fine, it may have something to do with the way you're filling up your form, or maybe a browser issue, I can't really tell.
im new to Django. Im creating a bidding site, where users should be able to visit a page to create a new listing (item that they are going to put up).The form that they are required to submit has a few common fields and when valid, the said form should be saved.
Problem is, my listingcreateview() is not doing that. I submit a correct form but it wont save, it just redirects to the same form page and No errors are shown.
This because the submitted form is validated as invalid every time. I know this because of the two functions i added inside listingcreateview(), the second one is called.
It was working properly before, dont know what changes messed it up. If i add in the admin interface information by hand, it is saved successfully.
views.py:
class ListingCreateView(CreateView):
model = Listing
fields = ['title', 'content', 'image', 'min_bid', 'categories']
def form_valid(self, form):
form.instance.seller = self.request.user
return super().form_valid(form)
def form_invalid(self, form):
return HttpResponseRedirect(reverse("index"))
models.py:
class User(AbstractUser):
pass
class Listing(models.Model):
id = models.IntegerField(primary_key=True)
title = models.CharField(max_length=100)
image = models.ImageField(blank=False, upload_to='media')
content = models.TextField()
date_posted = models.DateTimeField(default=timezone.now)
categories = models.CharField(max_length=25, choices = category)
seller = models.ForeignKey(User, on_delete=models.CASCADE) ##
min_bid = models.FloatField(blank=False)
image_thumbnail = ImageSpecField(source='image', processors=[ResizeToFill(300, 150)], format='JPEG', options={'quality':100})
def get_absolute_url(self):
return reverse('listing-detail', kwargs={'pk': self.pk})
listing_form.html:
{% extends "auctions/layout.html" %}
{% block body %}
<h2> Create Listing </h2>
{% if message %}
<div>{{ message }}</div>
{% endif %}
{% if messages %}
<div class="alert alert-warning" role="alert">
{{ messages }}
</div>
{% endif %}
<div class="container">
<form method="POST" action="">
{% csrf_token %}
<label class="label">{{ form.title.label }}</label>
<div class="input">{{ form.title }}</div>
<label class="label">{{ form.content.label }}</label>
<div class="input">{{ form.content }}</div>
<label class="label">{{ form.image.label }}</label>
<div class="input">{{ form.image }}</div>
<label class="label">Minimal bid</label>
<div class="input">{{ form.min_bid }}</div>
<label class="label">{{ form.categories.label }}</label>
<div class="input">{{ form.categories }}</div>
<input type="submit" value="Submit">
</form>
</div>
{% endblock %}
urls.py:
path("create-listing", login_required(ListingCreateView.as_view()), name="create-listing")
Your form is invalid because form is missing
enctype="multipart/form-data" which is needed for file uploads
Good morning guys, I have a problem with a form.
My code:
models.py
class AnagraficaGenerale(models.Model):
ragionesociale = models.CharField(max_length=40, null=True, blank=True)
cf = models.CharField(max_length=40, null=True, blank=True)
piva = models.CharField(max_length=40, null=True, blank=True)
forms.py
class AnagraficaGeneraleForm(forms.ModelForm):
class Meta:
model = AnagraficaGenerale
fields = '__all__'
views.py
#login_required
def anagrafica_new(request):
if request.method == "POST":
form = AnagraficaGeneraleForm(request.POST or None)
if form.is_valid():
form.save()
return redirect('anagrafica_list')
else:
form = AnagraficaGeneraleForm()
return render(request, 'Anagrafiche/anagrafica_new.html', {'form': form})
html
{% extends 'FBIsystem/basenobar.html' %}
{%load staticfiles %}
{% block content %}
<div id="page-wrapper">
<div class="panel">
<div class="panel-body">
<h3 class="title-hero">
Nuova Anagrafica
</h3>
<form method="POST" class="form-horizontal bordered-row">
{% csrf_token %}
<div class="example-box-wrapper">
<div class="form-group">
<label class="col-sm-2 control-label" > Ragione Sociale:</label>
<div class="col-sm-6">
{{ form.ragionesociale }}
</div>
</div>
</div>
<button type="submit" class="btn btn-primary btn-lg btn-block">Salva</button>
</form>
</div>
</div>
</div>
{% endblock %}
Everything seems ok but not save, if I try with {{form.as_table}} it save.
I think there is a problem with custom field but I don't know how.
whats wrong?
TY
I am working on a django web application. the application holds two forms in the same page. The first form is for uploading an image and the second form is a description for the image. After the user uploads an image and clicks on the upload image button, an image classifier should classify the image and autofill some parts of the second form.
This is my code so far
models.py
class Item(models.Model):
title = models.CharField(max_length=100)
color = models.CharField(max_length=100)
img = models.ImageField(upload_to='item/img/', null=False, blank=False)
def __str__(self):
return self.title
def delete(self, *args, **kwargs):
self.img.delete()
super().delete(*args, **kwargs)
forms.py
from .models import Item
class ItemImage(forms.ModelForm):
class Meta:
model = Item
fields = ('img',)
class ItemForm(forms.ModelForm):
class Meta:
model = Item
fields = ('title', 'color')
views.py
from .forms import ItemForm, ItemImage
from .models import Item
def upload_item(request):
if request.method == 'POST':
form_img = ItemImage(request.POST, request.FILES)
if form_img.is_valid():
form_img.save()
form_des = ItemForm(request.POST, request.FILES)
if form_des.is_valid():
form_des.save()
return redirect('item_list')
else:
form_img = ItemImage()
form_des = ItemForm()
return render(request, 'upload_item.html', {'form_img': form_img, 'form_des': form_des})
upload_item.html template
{% extends 'base.html' %}
{% load crispy_forms_tags %}
{% block title %} upload_item {% endblock title %}
{% block content %}
<div class="row justify-content-center">
<div class="col-6">
<h2>Upload item</h2>
<div class="card mb-5 mt-1">
<div class="card-body">
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{form_img|crispy}}
<button type="submit" class='btn btn-primary'>upload img</button>
</form>
</div>
</div>
<div class="card mb-5 mt-1">
<div class="card-body">
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{form_des|crispy}}
<button type="submit" class='btn btn-primary'>Save item</button>
</form>
</div>
</div>
</div>
</div>
{% endblock content %}
The problem I am facing is after uploading an image, when I press the upload image button, the page reloads and I have to start all over again. I guess when I press the button the the page is trying to save the form. how do I rectify this?
[NOTE] I have not written the image classification code yet. I will be writing that code under upload_item function in views.py once I solve this problem
[EDITS]
I made some changes to the template file. Now I am able to upload the image and run the classifier on the image.
These are the changes I made
upload_item.html template
{% block content %}
<div class="row justify-content-center">
<div class="col-6">
<h2>Upload item</h2>
<div class="card mb-5 mt-1">
<div class="card-body">
<form action="{{ request.build_absolute_uri }}image_classification/" method="POST" enctype="multipart/form-data">
{% csrf_token %}
<input id="search" , type="file" name="file"/>
<input class='btn btn-primary' , type="submit" value="Upload image" />
</form>
</div>
</div>
<div class="card mb-5 mt-1">
<div class="card-body">
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{form_des|crispy}}
<button type="submit" class='btn btn-primary'>Save item</button>
</form>
</div>
</div>
</div>
</div>
{% endblock content %}
views.py
def handle_uploaded_file(file, filename):
if not os.path.exists('media/classification/'):
os.mkdir('media/classification/')
with open('media/classification/' + filename, 'wb+') as destination:
for chunk in file.chunks():
destination.write(chunk)
def image_classification(request):
form = ItemForm()
cascade_path = "./classifier.h5"
classifier = load_model(cascade_path)
if request.method == 'POST':
handle_uploaded_file(request.FILES['file'], str(request.FILES['file']))
img = np.expand_dims(cv2.resize(cv2.imread(os.path.join('./media/classification/', str(request.FILES['file']))), (170, 100)), axis=0)
pred_class = str(classifier.predict_classes(img)[0])
print(pred_class)
form.fields['title'].widget.attrs['value'] = pred_class
return render(request, 'upload_item.html', {'form': form})
return HttpResponse("Failed")
I added the code #Alexander Strakhov suggested. This is the result I am getting.
What am I doing wrong?
Thanks in advance
When you press "upload image" button , you send a request to upload_item url. There your views:
1) bind the ItemImage form to request.Post, which is a QueryDict with csrf token and to request.FILES with your uploaded file.
2) save the image form (assuming that an image was valid).
3) bind ItemForm to the same request data as ItemImage.
4) render the upload_item.html again with bounded form_img and form_des in context.
Consult Django documentation: https://docs.djangoproject.com/en/2.1/topics/forms/#the-view
The reason why you get an empty page when you press "upload image" is that:
a) both fields Title and Color are bound to an empty value in QueryDict, as pressing "upload image" does not submit that second form, which Title and Color are part of.
b) It seems that Django does not bind a form to a file when rendering it back, leaving a form blank (I would consult community on this). I would suggest using AJAX here to validate you image and run classification later. Using AJAX would keep your image on the page, as there is no page refresh, allowing you to submit both forms later with "Save Item" button.
Edit
After seeing your updated code, I would recommend doing the following for starters:
Replace form.fields['title'].widget.attrs['placeholder'] = pred_class
With
form.fields['title'].widget.attrs['value'] = pred_class
return render(request, 'upload_item.html', {'form_des': form})