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
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
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__'
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.
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
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