Upload file with a text description - django

I can't manage to upload and save a file with a text value as a description. I don't understand why: the form and model clearly has the related fields. When I remove the reference to the text field tekst from my view, it does upload and save the file correctly. FYI: I am using a subdirectory structure basis one of the model fields, which is why there is def get_upload_to in my model and Overig_Beeld.objects.create in my view, rather than just upload.save().
Model:
def get_upload_to(instance, filename):
return 'bulkafbeeldingen/%s/%s' % (instance.bulknummer, filename)
class Overig_Beeld(models.Model):
file = models.FileField(upload_to=get_upload_to)
bestandnaam = models.CharField(max_length=256, null=True)
upload_date = models.DateTimeField(auto_now_add=True)
bulknummer = models.ForeignKey(Bulk, null=True)
tekst = models.CharField(max_length=512)
Form:
class Overig_BeeldForm(forms.ModelForm):
file = forms.FileField()
tekst = forms.CharField(required=False)
class Meta:
model = Overig_Beeld
fields = ('file', 'tekst')
template:
<form action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
<label for="file">Bestand:</label>
<input type="file" name="file"/>
<input type="text" name="tekst"/>
<input type="submit" value="Upload" />
</form>
View:
if request.method=="POST":
upload = Overig_BeeldForm(request.POST, request.FILES)
if upload.is_valid():
f = request.FILES['file']
Overig_Beeld.objects.create(file=f, bestandnaam=f.name, bulknummer=bulk, tekst=upload.tekst )
return redirect(reverse('bulk', args=(bulk.slug,)))
error:
'Overig_BeeldForm' object has no attribute 'tekst'

Uploaded data contains in cleaned_data attribute in django form's instance. So
text = upload.cleaned_data['tekst']
will fix your problem

Related

Saving image fails without error in django model form

I want to try to save an image to my model:
def user_directory_path(instance, filename):
# file will be uploaded to MEDIA_ROOT/user_<id>/<filename>
return 'user_{0}/{1}'.format(instance.user.id, filename)
class Leverandor(models.Model):
ID = models.AutoField(primary_key=True)
UserID = models.ForeignKey('Stamdata', on_delete=models.CASCADE)
Name = models.CharField('Name', max_length=200)
URL = models.URLField('URL', max_length=200)
ImageURL = models.ImageField('ImageURL',blank=True, null=True, upload_to=user_directory_path)
To this Form.py:
class EditLeverandorForm(forms.ModelForm):
Name = forms.CharField(widget=forms.TextInput(attrs={'class': 'form-control', 'autofocus': True}))
URL = forms.URLField(widget=forms.TextInput(attrs={'class': 'form-control', 'autofocus': True}))
ImageURL = forms.ImageField
class Meta:
model = Leverandor
labels = {
'Name' : 'Leverandør',
'URL' : 'Webside',
'ImageURL' : 'Logo',
}
fields = ['UserID', 'Name', 'URL', 'ImageURL']
And rendererd to this view.py
def add_leverandorer(request):
user_id = request.user.id
# if this is a POST request we need to process the form data
if request.method == 'POST':
print (user_id)
form = EditLeverandorForm(request.POST, request.FILES, instance=request.user)
if form.is_valid():
form.save()
return HttpResponseRedirect('/backend/leverandorer')
else:
print ('somethin goes wrong')
print (user_id)
form = EditLeverandorForm()
return render(
request,
'backend/add_leverandorer.html',
{
'title':'WestcoastShop - Backend',
'form': form,
}
)
The problem is that before I add the instance=request.user part its saves the entry correct but without image. Now I add the part from Django documentation like provided for save to an variable path but nothing happened after i click to save button.
<form action="/backend/leverandorer/add" method="post" enctype="multipart/form-data">
{% csrf_token %}
<div class="form-group">
<label for="simpleinput">Leverandør</label>
{{ form.Name }}
</div>
<div class="form-group">
<label for="simpleinput">Webside</label>
{{ form.URL }}
</div>
<div class="form-group">
<label for="simpleinput">Logo</label>
{{ form.ImageURL }}
<!--<input type="file" name="ImageURL" accept="image/*" required="" id="id_ImageURL" class="form-control-file">-->
</div>
<input type="hidden" id="UserID" name="UserID" value="{{ user.id }}">
<button type="submit" class="btn btn-primary">Gem</button>
</form>
I didnt see an error but now its not saving the form in models also if ImageField is empty.
regards
Christopher.
You are using UserID as a hidden field. The hidden field will not pass the form-validation. So your following code will be false.
if form.is_valid():
form.save()
return HttpResponseRedirect('/backend/leverandorer')
One of the solutions is, remove the UserID field from your template and update your view as follows.
if form.is_valid():
user_form = form.save(commit=False)
user_form.UserID = request.user
user_form.save()
I I change the function in models.py to:
def user_directory_path(instance, filename):
# file will be uploaded to MEDIA_ROOT/user_<id>/<filename>
return 'user_{0}/{1}'.format(instance.UserID, filename)
class Leverandor(models.Model):
ID = models.AutoField(primary_key=True)
UserID = models.ForeignKey('Stamdata', on_delete=models.CASCADE)
Name = models.CharField('Name', max_length=200)
URL = models.URLField('URL', max_length=200)
ImageURL = models.ImageField('ImageURL',blank=True, null=True, upload_to=user_directory_path)
its works, but the Path is Username and not user.id

How to upload multiple images with one value in Django

I'm trying to upload multiple images with one single field, in a Django application.
How to do this?
The following files are involved:
upload.html:
<form action="#" method="post" enctype="multipart/form-data">
{% csrf_token %}
<input type="text" name="image_id" placeholder="Image Id">
<input type="file" name="file" multiple>
<button type="submit"> Upload </button>
</form>
Here, the single field image_id is meant to hold 5 images.
views.py:
def multi_image(request):
if request.method == 'POST':
img_id = request.POST.get('image_id')
file = request.FILES.getlist('file')
data_save = Res(image_id = img_id )
data_save.save()
filter_data = Res.objects.filter(image_id= img_id)
if len(filter_data) > 0:
for i in file:
print(i)
Res.objects.create(image= i)
return render(request, 'upload.html', {})
models.py:
class Res(models.Model):
image_id= models.CharField(max_length=10, blank=True, null=True)
image = models.FileField(upload_to='images', blank=True, null=True)
forms.py:
class FileForm(forms.Form):
class Meta:
model = Res
fields = '__all__'

'PersonForm' object has no attribute 'as_widget'

I am trying to pass string to a hidden field scenario of a form whose data is stored in a database. The goal is to be able to retrieve extra information on client side without having it as another field of the form.
I am getting 'PersonForm' object has no attribute 'as_widget' error.
This is my Model:
class Person(models.Model):
region = models.CharField(max_length=30)
industry = models.CharField(max_length=30)
uuid = models.CharField(max_length=50, blank=True, unique=True, default=uuid.uuid4)
scenario = models.ForeignKey(Scenario, on_delete=models.CASCADE,)
def __str__(self):
return "{}".format(self.uuid)
My Form
class PersonForm(forms.ModelForm):
class Meta:
model=Person
scenario = forms.CharField(widget=forms.HiddenInput())
fields = ['industry', 'region','scenario']
My View
def personforms(request):
persons = Person.objects.all()
if request.method == 'POST':
filled_form = PersonForm(request.POST)
if filled_form.is_valid():
created_person = filled_form.save()
#DEBUG
print(filled_form.cleaned_data['scenario'])
created_person_pk = created_person.id
filled_form = PersonForm()
return redirect('/scenariopage', {'persons':persons})
else:
created_person_pk = None
return render(request, 'core/scenario-landing-page.html', {'personform':filled_form, 'created_person_pk':created_person_pk})
else:
form = PersonForm()
return render(request, 'core/scenario-landing-page.html', {'personform':form})
And my template
<form action="{% url 'personform' %}" method="post" class="custom-form">
{% csrf_token %}
{% render_field personform class="form-control" %}
{% render_field personform.scenario class="form-control form-control-sm" value='{{ scenario.name }}' %}
<input type="submit" class="btn color-btn" value="Go to Scenario page" data-dismiss="gallery-item"/>
</form>
Questions I have:
I have no Error message. But debug print is indicating that filled_form.is_valid(): seems to be invalid.
And this line in the View never print result:
#DEBUG
print(filled_form.cleaned_data['scenario'])
What I am doing wrong?
How could I possibly pass the data to the field scenario.

How do i upload image to database from django form?

I have tried this but did not work.
class Agent(models.Model):
first_name = models.CharField(max_length=50, blank=False)
last_name = models.CharField(max_length=50, blank=False)
email = models.EmailField(blank=False)
cellPhone = models.IntegerField(blank=False)
picture = models.ImageField(blank=False)
class AgentForm(forms.ModelForm):
class Meta:
model = Agent
fields = ('first_name','last_name','cellPhone','email', 'picture')
<form method="POST" class="post-form" enctype="multipart/form-data">{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="save btn btn-default">Save</button>
</form>
I select the file using the form button but it says "the field is required".
I think it didn't work because you didn't mention the request.FILES in your views.py.
Whitout the request.FILES you can not receive the file uploaded.
form = AgentForm(request.POST, request.FILES)
If your user is uploading pictures, you need to have your MEDIA_ROOT settings on-point. Documentation

Django - Display imagefield in ManytoMany form instead of title

I am working on a Django project with crispy forms.
I want to use images instead of the the default Models title/label to select a instance in a Many to Many relation form.
Content models.py:
class Cloth(models.Model):
owner = models.ForeignKey(settings.AUTH_USER_MODEL)
title = models.CharField(max_length=200)
picture = ImageCropField(upload_to='cloth_pics/%Y-%m-%d/',
blank=True)
def __str__(self):
return self.title
class Outfit(models.Model):
owner = models.ForeignKey('profiles.Profile')
title = models.CharField(max_length=200)
cloths=models.ManyToManyField(Cloth)
Content forms.py
class ClothForm(forms.ModelForm):
class Meta:
model = Cloth
fields = ('title','type','picture')
class OutfitForm(forms.ModelForm):
class Meta:
model = Outfit
exclude= ["owner"]
Content views.py
def outfits_new(request):
if request.method == "POST":
form = OutfitForm(request.POST)
if form.is_valid():
outfit = form.save(commit=False)
outfit.owner = get_user(request)
outfit.created_date = timezone.now()
outfit.save()
pk=outfit.id
return HttpResponseRedirect(reverse('outfit_edit_delete', args=[pk]))
else:
cloths = Cloth.objects.filter(owner=request.user.id)
form = OutfitForm()
return render(request, '../templates/outfits_new.html', {'form': form, "cloths":cloths})
Content outfits_new.html
<form enctype="multipart/form-data" method="post">
{% csrf_token %}
{{ form|crispy }}
<div class="btn-group" role="group" aria-label="Basic example">
<input type="submit" value="Submit" name="edit" class="btn btn-success">
</div>
This code produces a Outfit form where I can select different cloths( displaying the cloths title). I want to select different cloths using a image from the cloths.picture field.
Thank you very much,
Patrick
Have a look at select2 at https://select2.github.io/examples.html. It allows you to do images in comboboxes
There is a Django package at https://github.com/applegrew/django-select2