How do i upload image to database from django form? - django

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

Related

Django's Generic UpdateView: How to pass value to the hidden form field?

I am trying to combine Django's generic UpdateView and hidden input field. My purpose is to track whether a post was edited after it was created or not. Hidden field name is "updated".
views.py:
class PostUpdateView(UpdateView):
model = Post
template_name = 'journal/post_update_form.html'
form_class = PostUpdateForm
success_url = reverse_lazy('my_posts')
models.py:
class Post(models.Model):
title = models.CharField(max_length=500)
text = models.TextField(max_length=2000, null=True, blank=True)
owner = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True)
#storing the link to media files in CharField
image = models.CharField(max_length=500, null=True, blank=True)
audio = models.CharField(max_length=500, null=True, blank=True)
video = models.CharField(max_length=500, null=True, blank=True)
rubric = models.CharField(max_length=100, default="No rubric", choices=RUBRIC_CHOICES)
private = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
updated = models.CharField(max_length=10, default="False")
forms.py:
from django import forms
from .models import Post
class PostUpdateForm(forms.ModelForm):
class Meta:
model = Post
fields = ["title", "text", "image", "audio", "video", "rubric", "private", "updated"]
widgets = {'updated': forms.HiddenInput(attrs={'value':"updated"})}
relevant part of update form template:
<form action="" method="POST">
{% csrf_token %}
{% for field in form %}
{% if field != form.rubric and field != form.private %}
<div class="mb-3 form-group">
<label for="{{field.name}}" class="form-label">{{field.label}}</label>
{{field.errors}}
{% if field == form.text %}
<textarea type="text" class="form-control" id="{{field.name}}" name="{{field.name}}">{{field.value|default_if_none:"" }}</textarea>
{% elif field == form.updated %}
<input type="hidden" id="{{field.name}}" name="{{field.name}}" value="updated">
{% else %}
<input type="text" class="form-control" id="{{field.name}}" name="{{field.name}}" value="{{field.value|default_if_none:"" }}">
{% endif %}
</div>
<...some other fields...>
{% endif %}
{% endfor %}
<input type="submit" class="btn btn-primary" value="Update"/>
</form>
Value of "updated" field is passed successfully, but the field value is visible (non-editable).
In forms.py I tried to:
exclude 'updated' from fields list. Result: the value of "updated" is not saved.
use "widgets = {'updated': forms.HiddenInput}". Result: value is also passed successfully, but the field is still visible.
use only widgets in forms.py and comment out input field [1] in the template. Result: field is visible, editable, value is not saved.
[1] input field:
{% elif field == form.updated %}
<input type="hidden" id="{{field.name}}" name="{{field.name}}" value="updated">
I would appreciate any insights about what might be wrong here. Thank you in advance.
In PostUpdateForm you can do so:
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['updated'].initial = 'updated'
self.fields['updated'].disabled = True
https://docs.djangoproject.com/en/4.1/ref/forms/fields/#disabled

how can I add Image to my django database and display it in frontend

I am making a blogging website in Django. I want to add a functionality with which the user can upload an image in the form, which will be used as a thumbnail for that blog. I have added imageField in models.py file, now I am not getting how shall I take the image input from the user in the form section?
post models.py:
class Post(models.Model):
sno = models.AutoField(primary_key=True)
thumbnail = models.ImageField(null=True, blank=True, upload_to="images/")
title = models.CharField(max_length=50)
content = RichTextField(blank=True, null=True)
author = models.CharField(max_length=50)
slug = models.CharField(max_length=200)
timeStamp = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ['-timeStamp']
def __str__(self):
return self.title + " by " + self.author
html forms:
<form action = "{% url 'addblog' %}" method="post">
<div class="form-group">
<label for="title" id="Title">Title</label>
<input type="text" class="form-control" id="title" name="title"/>
</div>
{% csrf_token %}
<div class="form-group">
<textarea name="content"></textarea>
<script type = 'text/javascript'>
CKEDITOR.replace("content")
</script>
</div>
<button type="submit" class="btn btn-primary my-1" id='contact-button'>Post</button>
</form>
currently the add blog page looks like this:
now I want a choose file option after the content text area where the user can upload an image and then that image gets saved in the database, after which I can display the image in the blog section at frontend.
pip install pillow
change <form> to this:
<form method="post" enctype="multipart/form-data">
<input type='file' name='imagefile'>
require "multipart/form-data" to send image or file from form.
in settings.py add code:
MEDIA_URL = '/media/'
in views.py
if you are using function based view, do this:
image = request.FILES.get('imagefile')
post = Post()
post.thumbnail=image
add other fields of the model.
save model by using post.save() command.
image.filename returns new file name of the image.
it will directly save image in media/images/ folder

Upload file with a text description

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

Django foreign key drop down

New to Django and Python and I need a little help with a foreign key drop down. Basically, I have a category model and a image model and I want users to be able to choose which category to put the image in. How do I create a drop down for the category in the image form? Are my views and html correct too? I have had a look online but I can't seem to do it myself. I keep getting errors.
Here are my models:
class Images(models.Model):
image = models.ImageField(upload_to='images', blank=False)
img_name = models.CharField(max_length=120, blank=True)
img_date = models.DateTimeField(default=now())
img_user = models.ForeignKey(User)
img_cat_id = models.ForeignKey(Categories)
def __unicode__(self):
return self.img_name
class Categories(models.Model):
cat_descr = models.CharField(max_length =120, blank=False)
def __unicode__(self):
return self.cat_descr
VIEWS:
#login_required
def upload_images(request):
context = RequestContext(request)
context_dict={}
if request.method == 'POST': # render the form, and throw it back.
# take the form data and process it!
form = UploadImagesForm(request.POST, request.FILES)
if form.is_valid():
print 'form is_valid'
upload_image = form.save(commit=False)
upload_image.img_user = request.user
if 'image' in request.FILES:
upload_image.image =request.FILES['image']
upload_image.save()
return render(request, 'rmb/upload.html', {'upload_image': form})
else:
print form.errors
# Not a HTTP POST, so we render our form using two ModelForm instances.
# These forms will be blank, ready for user input.
else:
form = UploadImagesForm()
context_dict = {'upload_image': form}
all_categories = Categories.objects.order_by('-id')
context_dict['all_categories'] = all_categories
print context_dict
return render_to_response('rmb/upload.html', context_dict, context)
FORMS:
class UploadImagesForm(forms.ModelForm):
#cat_list = ModelChoiceField(queryset=Categories.objects.all())
class Meta:
model = Images
fields=('image','img_name')
HTML:
{% block body_block %}
<form id="upload_form" method="post" action="/rmb/upload/"
enctype="multipart/form-data">
{% csrf_token %}
{{ upload_image.as_table }}
<input type="submit" name="submit" value="Upload" />
{% for categories in all_categories %}
<div> {{ categories.id }} </div>
{{ categories.cat_descr }}
<input type="submit" name="submit" value="Upload" />
{% endfor %}
</form>
{% endblock %}
You don't need to insert the HTML for the form manually, just use {{form}} in the template.
{% block body_block %}
<form id="upload_form" method="post" action="/rmb/upload/"
enctype="multipart/form-data">
{% csrf_token %}
{{ form }}
</form>
{% endblock %}
By default a ForeignKey will be a select field so you shouldn't need to do much else.
As an aside, give your models and fields more appropriate names. We know these are all image fields, because they are on the image and make sure, unless your model is a collection of things, you give it a singular name. Lastly, when using a Foreign Key and item gets an extra field of fieldname_id that is just the ID, whereas fieldname is the property that gives the related item as well.
So instead of:
class Images(models.Model):
image = models.ImageField(upload_to='images', blank=False)
img_name = models.CharField(max_length=120, blank=True)
img_date = models.DateTimeField(default=now())
img_user = models.ForeignKey(User)
img_cat_id = models.ForeignKey(Categories)
Use:
class Image(models.Model):
image = models.ImageField(upload_to='images', blank=False)
name = models.CharField(max_length=120, blank=True)
date = models.DateTimeField(default=now())
user = models.ForeignKey(User)
category = models.ForeignKey(Categories)

Django FileField upload is not working for me

I have been scratching my head FileField. Does the FileField require a seperate process?
Although my url gets saved .. but my file doesn't get uploaded ... what am i doing wrong?
This is my models.py ...
class OpLink(models.Model):
user = models.ForeignKey(User)
file = models.FileField(blank=True, null=True, upload_to="uploads")
url = models.URLField(blank=True, null=True)
my forms.py
class OpLinkForm(ModelForm):
class Meta:
model = OpLink
exclude = ('user')
my views.py
oplinkform = oplinkform(request.POST)
oplink = oplinkform.save(commit=False)
oplink.user = user
oplink.save()
and my html to process it.
<div class="span5">
{{ oplinkform.url|add_class:"span4"|attr:"Placeholder:URL for the item" }}
<br><h4>OR</h4><br>
{{ oplinkform.file|add_class:"input-file" }}
<br />
<input class='btn btn-primary btn-large' type="submit" value='Post' name='action'>
</div>
You need to include the files when creating the form
oplinkform = oplinkform(request.POST, request.FILES)
Also make sure that your form has the correct enctype
<form enctype="multipart/form-data"></form>