Image not uploading to the folder - django

I want to upload an Image, but it is not showing in the media folder.
This is the HTML template
<form class="form" action="/profile/edit/{{user.id}}" method="post" enctype="multipart/form-data" style="padding-top:20px;">
{% csrf_token %}
<input type="file" class="btn " name="pro_pic" accept=".png, .jpg, .jpeg">
<button type="submit" class="btn text-success" name="pr_pic" id="pic_submit"><i class="fas fa-check"></i> Submit</button>
</form>
Models.py
class UserDetails(models.Model):
user_id = models.IntegerField(unique=True)
bio = models.TextField(null = True)
profession = models.CharField(max_length = 100, null = True)
city = models.CharField(max_length = 100, null = True)
country = models.CharField(max_length = 100, null = True)
img = models.ImageField(upload_to='pic_user', null = True)
views.py
def edit (request, id = '') :
if request.user.is_authenticated == True :
if request.method == 'POST' :
# MyModel.objects.filter(pk=some_value).update(field1='some value')
if request.POST.get('pr_pic') == '' :
post_image = request.FILES['pro_pic']
# pic = UserDetails.objects.filter(user_id = id).update(img = post_image)
# UserDetails.objects.filter(user_id = id).update(img = post_image)
pic = UserDetails.objects.filter(user_id = id)
pic.img = post_image
pic.save()
Whenever an user is created his user_id gets updated in another table(UserDetails model), and the fields are null.
But in the HTML ive an option to upload image later (that ive shown in the HTML).
I think my views.py is wrong, please help me correct it

Try:
import uuid
from PIL import Image
format_image, img_str = request.FILES['pro_pic'].split(';base64,')
file_content = ContentFile(base64.b64decode(img_str))
unique_filename = str(uuid.uuid4())
pic.img.save(unique_filename, file_content)
file_url = settings.MEDIA_FILES + '/tmp/' + unique_filename
# convert image into JPEG format and save
img = Image.open(file_url)
img.save(file_url, format='jpeg', optimize=True, quality=85)

Related

How to save from html select to sql in django

I want to save from HTML select to SQL but "Cannot assign "'27'": "UserProduct.category" must be a "Category" instance." I get an error. What am I doing wrong?
sell.html
<div class="form-group">
<p>Yerləşdirdiyiniz məhsul "İkinci əl məhsullar" kateqoriyasında görünəcək.</p>
<select class="input search-categories" name="up_category">
<option value="0">Kateqoriya seç</option>
{% for category in category %}
{% if category.active %}
{% if category.parent_id %}
<option value="{{category.id}}">{{category.name}}</option>
{% else %}
<option value="{{category.id}}" style="font-weight: bold;">{{category.name}}</option>
{% endif %}
{% endif %}
{% endfor %}
</select>
</div>
views.py
def sell(request):
category = Category.objects.all()
context = {'category': category}
if request.POST:
product_name = request.POST.get('product_name')
up_category = request.POST.get('up_category')
keywords = request.POST.get('keywords')
descriptions = request.POST.get('descriptions')
main_image = request.POST.get('main_image')
price = request.POST.get('price')
detail = request.POST.get('detail')
image1 = request.POST.get('image1')
image2 = request.POST.get('image2')
image3 = request.POST.get('image3')
if product_name == '' or up_category == 'Kateqoriya seç' or keywords == '' or descriptions == '' or price == '' or price == str or detail == '':
messages.warning(request, 'Bütün xanaları doldurduğunuzdan əmin olun!')
else:
newUserProduct = UserProduct(user=request.user,
name=product_name,
category=up_category,
keywords=keywords,
descriptions=descriptions,
detail=detail,
main_image=main_image,
image1 = image1,
image2 = image2,
image3 =image3
)
newUserProduct.save()
messages.warning(request, 'Məhsulunuz satışa çıxdı.')
return render(request, 'forms/sell.html', context)
return render(request, 'forms/sell.html', context)
models.py
class UserProduct(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, default=False)
name = models.CharField(max_length=100)
category = models.ForeignKey(Category, on_delete=models.DO_NOTHING)
main_image = models.ImageField(upload_to='static/product_images/%Y/%m/%d/')
detail = models.TextField()
keywords = models.CharField(max_length=50)
description = models.CharField(max_length=1000)
price = models.FloatField()
sale = models.IntegerField(blank=True, null=True, verbose_name="Sale (%)")
image1 = models.ImageField(upload_to='static/product_images/%Y/%m/%d/', blank=True, null=True)
image2 = models.ImageField(upload_to='static/product_images/%Y/%m/%d/', blank=True, null=True)
image3 = models.ImageField(upload_to='static/product_images/%Y/%m/%d/', blank=True, null=True)
date_created = models.DateTimeField(auto_now_add=True)
I want to save from HTML select to SQL but "Cannot assign "'27'": "UserProduct.category" must be a "Category" instance." I get an error. What am I doing wrong?
In your UserProduct class, the field category is a ForeignKey to the Category class. Try getting the Category first from your request.POST, then adding it:
def sell(request):
category = Category.objects.all()
context = {'category': category}
if request.POST:
product_name = request.POST.get('product_name')
up_category = request.POST.get('up_category')
keywords = request.POST.get('keywords')
descriptions = request.POST.get('descriptions')
main_image = request.POST.get('main_image')
price = request.POST.get('price')
detail = request.POST.get('detail')
image1 = request.POST.get('image1')
image2 = request.POST.get('image2')
image3 = request.POST.get('image3')
if product_name == '' or up_category == 'Kateqoriya seç' or keywords == '' or descriptions == '' or price == '' or price == str or detail == '':
messages.warning(request, 'Bütün xanaları doldurduğunuzdan əmin olun!')
else:
cat = Category.objects.get(pk=up_category) # CHANGED
newUserProduct = UserProduct(user=request.user,
name=product_name,
category=cat, # CHANGED
keywords=keywords,
descriptions=descriptions,
detail=detail,
main_image=main_image,
image1 = image1,
image2 = image2,
image3 =image3
)
newUserProduct.save()
messages.warning(request, 'Məhsulunuz satışa çıxdı.')
return render(request, 'forms/sell.html', context)
return render(request, 'forms/sell.html', context)

How to display your queries using filter?

So I am trying to set up a filter for my website and it is not working; It does not give me an error and the url updates like a query is being made but when I click "submit" it still shows all of the content in the page. I can't quite figure out what is wrong.
filters.py
import django_filters
from django_filters import DateFilter
from .models import *
class UserpostFilter(django_filters.FilterSet):
start_date = DateFilter(field_name = "date_published", lookup_expr='gte')
end_date = DateFilter(field_name = "date_published", lookup_expr='lte')
class Meta:
model = Userpost
fields = '__all__'
exclude = ['image', 'user', 'date_published']
models.py
class Userpost(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True)
Year = models.CharField(max_length = 4)
Mileage = models.CharField(max_length = 8)
Make = models.CharField(max_length = 50)
Model = models.CharField(max_length = 50)
Price = models.DecimalField(max_digits=15, decimal_places=2)
email = models.EmailField()
date_published = models.DateField(default = timezone.now)
image = models.ImageField(null = True, blank = True, upload_to = r"C:\Users\gabri\Desktop\test\ecommerce\static\images")
def __str__(self):
return self.Year + " " + self.Make + " " + self.Model
#property
def imageURL(self):
try:
url = self.image.url
except:
url = ''
return url
views.py
def posts(request):
cars = Userpost.objects.all()
p = Paginator(Userpost.objects.all(), 9)
page = request.GET.get('page')
cars_list = p.get_page(page)
nums = "a" * cars_list.paginator.num_pages
myFilter = UserpostFilter(request.GET, queryset = cars)
cars = myFilter.qs
context = {'cars':cars, 'cars_list':cars_list, "nums":nums, "myFilter":myFilter}
return render(request, 'store/userposts.html', context)
userposts.html
<div class = "row">
<div class="col">
<div class = "card card-body">
<form method="get">
{{myFilter.form}}
<button class="btn btn-primary" type="submit">Search</button>
</form>
</div>
</div>
</div>
<br>
<div class="row">
{% for car in cars_list %}
<div class="col-lg-4">
<img class="thumbnail" src="{{car.imageURL|default:'/images/transparentLogo.png'}}">
<div class="box-element product">
<h6><strong>{{car.Year}} {{car.Make}} {{car.Model}}</strong></h6>
<hr>
<a class="btn btn-outline-success" href="{% url 'post_detail' car.pk %}">View</a>
<h4 style="display: inline-block; float: right"><strong>${{car.Price|floatformat:2}}</strong></h4>
</div>
</div>
{% endfor %}
</div>
I would really appreciate if you guys could help me
EDIT
So I changed the order of the views to first filter and then paginate but it still does the same thing. I get no error, but display all the content from the page rather than the filtered ones.
def posts(request):
cars = Userpost.objects.all()
myFilter = UserpostFilter(request.GET, queryset=cars)
cars = myFilter.qs
p = Paginator(Userpost.objects.all(), 9)
page = request.GET.get('page')
cars_list = p.get_page(page)
nums = "a" * cars_list.paginator.num_pages
context = {'cars':cars, "myFilter":myFilter, 'cars_list':cars_list, "nums":nums}
return render(request, 'store/userposts.html', context)
The paginator should work on the cars not on the orignal queryset, since you are paginate over the filtered results
def posts(request):
cars = Userpost.objects.all()
myFilter = UserpostFilter(request.GET, queryset=cars)
if not myFilter.is_valid():
raise ValidationError('filter is invalid')
cars = myFilter.qs
# This is the change
p = Paginator(cars, 9)
page = request.GET.get('page')
cars_list = p.get_page(page)
nums = "a" * cars_list.paginator.num_pages
context = {'cars':cars, "myFilter":myFilter, 'cars_list':cars_list, "nums":nums}
return render(request, 'store/userposts.html', context)

'str' object has no attribute 'objects' django

My views.py file is
def studentFeedBack(request):
studentid = ''
courseid = ''
teacherid = ''
if request.method == 'POST':
studentid_id = request.POST.get("studentid")
studentid = studentid.objects.get(id=studentid_id)
courseid_id = request.POST.get("courseid")
courseid = courseid.objects.get(id=courseid_id)
teacherid_id = request.POST.get("teacherid")
teacherid = teacherid.objects.get(id=teacherid_id)
description = request.POST.get("description")
rating = request.POST.get("rating")
studentFeedBack.objects.create(
courseid=courseid,
description=description,
studentid=studentid,
teacherid=teacherid,
rating=rating
)
return render(
request,
'forms/studentFeedBack.html',
{
'studentids':studentid.objects.all(),
'courseids':courseid.objects.all(),
'teacherids':teacherid.objects.all(),
}
)
and my models.py file is
class StudentFeedBack(models.Model):
feedbackid = models.AutoField(primary_key=True)
courseid = models.ForeignKey('Course', on_delete=models.CASCADE)
description = models.CharField(max_length=500)
submitdate = models.DateTimeField(auto_now_add=True)
teacherid = models.ForeignKey('schoolTeacher', on_delete=models.CASCADE)
studentid = models.ForeignKey('Student', on_delete=models.CASCADE)
option = [('Good','Good'),('Average','Average'),('Bad','Bad')]
rating = models.CharField(max_length=100, choices=option, default='none')
class Course(models.Model):
courseid = models.IntegerField(primary_key=True)
coursedescription = models.CharField(max_length=500)
coursename = models.CharField(max_length=50)
userid = models.IntegerField()
code = models.CharField(max_length=50)
videolink = models.FileField(default='default_link')
createddate = models.DateTimeField()
imagelink = models.URLField(default='default_link')
duration = models.DateTimeField()
longdes = models.TextField()
coursetype = models.CharField(max_length=50)
assignto = models.CharField(max_length=200)
status = models.BinaryField()
def _str_(self):
return self.coursename
class Meta:
db_table = "courseids"
class schoolTeacher(models.Model):
teacherid = models.IntegerField(primary_key=True)
name = models.CharField(max_length=50)
address = models.CharField(max_length=200)
email = models.EmailField()
contact = models.IntegerField()
passowrd = models.CharField(max_length=13)
image = models.ImageField(default='default.jpg')
regno = models.CharField(max_length=20)
joiningdate = models.DateTimeField()
def _str_(self):
return self.name
class Meta:
db_table = "teacherids"
class Student(models.Model):
studentid = models.IntegerField(primary_key=True)
regno = models.CharField(max_length=20)
name = models.CharField(max_length=50)
email = models.EmailField(max_length=50)
contactno = models.CharField(max_length=13)
registrationdate = models.DateTimeField()
address = models.CharField(max_length=200)
password = models.CharField(max_length=13)
imagepath = models.ImageField(max_length=100, default='default.jpg')
sectionid = models.IntegerField()
def _str_(self):
return self.name
class Meta:
db_table = "studentids"
and studentFeedBack html file has the following form
<form action="/studentFeedBack/" method="POST">
{% csrf_token %}
<label for="studentid">Student Id</label>
<!-- <input type="number" name="studentid"><br><br> -->
<select name="studentid" required>
{% for studentid in studentids %}
<option value="{{studentid.id}}">{{studentid.name}}</option>
{% endfor %}
</select><br><br>
<!-- <label for="courseid">Course Id</label>
<input type="number" name="courseid"><br><br> -->
<label for="courseid">Course Id</label>
<select name="courseid" required>
{% for courseid in courseids %}
<option value="{{courseid.id}}">{{courseid.coursename}}</option>
{% endfor %}
</select><br><br>
<label for="teacherid">Teacher Id</label>
<!-- <input type="number" name="teacherid"><br><br> -->
<select name="teacherid" required>
{% for teacherid in teacherids %}
<option value="{{teacherid.id}}">{{teacherid.name}}</option>
{% endfor %}
</select><br><br>
<label for="description" >Feedback</label>
<textarea class="form-control" rows="3" name="description"></textarea><br><br>
<label for="rating">Rating</label><br>
<input type="radio" id="Good" name="rating" value="Good">
<label for="Good">Good</label><br>
<input type="radio" id="Average" name="rating" value="Average">
<label for="Average">Average</label><br>
<input type="radio" id="Bad" name="rating" value="Bad">
<label for="Bad">Bad</label><br><br>
<button type="submit" class="btn btn-primary" >Submit</button>
</form>
The studentFeedBack model has foreign keys from student, schoolTeacher and Course. This is giving error on browser that 'str' object has no attribute 'objects'
Other than that my form is not giving any values in select options and that is also probably because of this error.
The design of the view is the issue
According to the line
studentid =''
studentid remains a string . You could try proper importation of the models.
Try:
views.py
from .models import Course, Student,schoolTeacher,studentFeedBack
def studentFeedBack(request):
#studentid = ''
#courseid = ''
#teacherid = ''
if request.method == 'POST':
studentid_id = request.POST.get("studentid")
studentid = Student.objects.get(id=studentid_id)
courseid_id = request.POST.get("courseid")
courseid = Course.objects.get(id=courseid_id)
teacherid_id = request.POST.get("teacherid")
teacherid = schoolTeacher.objects.get(id=teacherid_id)
description = request.POST.get("description")
rating = request.POST.get("rating")
studentFeedBack.objects.create(
courseid=courseid,
description=description,
studentid=studentid,
teacherid=teacherid,
rating=rating
)
return render(
request,
'forms/studentFeedBack.html',
{
'studentids':Student.objects.all(),
'courseids':Course.objects.all(),
'teacherids':schoolTeacher.objects.all(),
}
)
Alternatively, Django is superb at handing forms for models
https://docs.djangoproject.com/en/3.1/topics/forms/modelforms/#modelform
This will be better for your view as there is no validation at the moment
You could also have:
views.py
...
from django.forms.models import modelform_factory
from .models import studentFeedBack
def studentFeedBack(request):
fields=[
'courseid','description','studentid','teacherid','rating']
form=modelform_factory(studentFeedBack, fields=fields)
if request.method == 'POST':
form=modelform_factory(studentFeedBack, fields=fields, data=request.POST)
## Validates the data submitted
if form.is_valid():
## Creates a studentFeedBack instance
form.save()
## If form is invalid, it will fall through to the template with the incorrect data.
else:
### Handle the incorrect form
pass
return render(
request,
'forms/studentFeedBack.html',
{
'studentids':Student.objects.all(),
'courseids':Course.objects.all(),
'teacherids':schoolTeacher.objects.all(),
'form':form,
}
)
forms/studentFeedBack.html
<form action="/studentFeedBack/" method="POST">
{% csrf_token %}
{{form.as_p}}
</form>
https://docs.djangoproject.com/en/3.1/topics/forms/#working-with-form-templates
You may need to add a verbose_name attribute to your model fields:
models.py
class StudentFeedBack(models.Model):
...
teacherid = models.ForeignKey('schoolTeacher', on_delete=models.CASCADE, verbose_name="Teacher")
...
https://docs.djangoproject.com/en/3.1/ref/models/fields/#verbose-name
Customize as needed.
I hope this helps you understand Django better.
Edit
The function-based view has the same name as an imported model
For the first view:
from .models import Course, Student,schoolTeacher
from .models import studentFeedBack as studentFeedBackModel
def studentFeedBack(request):
#studentid = ''
#courseid = ''
#teacherid = ''
if request.method == 'POST':
studentid_id = request.POST.get("studentid")
studentid = Student.objects.get(id=studentid_id)
courseid_id = request.POST.get("courseid")
courseid = Course.objects.get(id=courseid_id)
teacherid_id = request.POST.get("teacherid")
teacherid = schoolTeacher.objects.get(id=teacherid_id)
description = request.POST.get("description")
rating = request.POST.get("rating")
studentFeedBackModel.objects.create(
courseid=courseid,
description=description,
studentid=studentid,
teacherid=teacherid,
rating=rating
)
return render(
request,
'forms/studentFeedBack.html',
{
'studentids':Student.objects.all(),
'courseids':Course.objects.all(),
'teacherids':schoolTeacher.objects.all(),
}
)

Displaying an image in a Django template

I have these three models -- A "Thing" has an associated "Album", which contains typically three or four "Photo"s of the "Thing". For the latest nine "Thing"s, I want to display the first photo of the thing from the "Album", along with other details of the thing (e.g., name, country of manufacture) using a template called "headquarters.html".
The following are my models:
class Thing(models.Model):
name = models.CharField(verbose_name = "Item", max_length = 60)
price = models.DecimalField(max_digits = 5, decimal_places = 2)
country_of_manufacture = models.CharField(verbose_name = "Country of Manufacture", max_length = 40)
created_on = models.DateTimeField(verbose_name = "Creation Date", default = django.utils.timezone.now, editable = False)
album = models.OneToOneField(Album, on_delete = models.CASCADE, null = True)
def __str__(self):
return self.name
class Album(models.Model):
name = models.CharField(verbose_name = "Photo Album", max_length = 60)
created_on = models.DateTimeField(verbose_name = "Creation Date", default = django.utils.timezone.now, editable = False)
def __str__(self):
return self.name
class Photo(models.Model):
photo_identity = models.ImageField(blank = True, null = True, upload_to="media/%Y/%m/%d/")
photo_in = models.ForeignKey(Album, on_delete = models.PROTECT)
uploaded_on = models.DateTimeField(verbose_name = "Creation Date", default = django.utils.timezone.now, editable = False)
def __str__(self):
return '%s -- (%s)' % (self.photo_in.name + " Album", self.photo_identity)
This is my view.py:
def headquarters(request, *args, **kwargs):
last_nine = Thing.objects.all().order_by('-id')[:9]
mylist = []
for thing in last_nine:
mylist.append (thing.album.photo_set.first().photo_identity)
return render(request, 'headquarters.html', {"nine_items" : last_nine, "URL_list" : mylist})
This is my template (headquarters.html):
{% for item in nine_items %}
<div class="col-lg-4 col-sm-6 portfolio-item">
<div class="card h-100">
<img class="card-img-top" src="{{ **what_do_put_in_here** }}" alt="">
<div class="card-body">
<h4 class="card-title">
{{item.name}}
</h4>
<p class="card-text">Brand: {{item.brand}}</p>
<p class="card-text">Item ID: {{item.id}}</p>
<p class="card-text">Item price: {{item.price}}</p>
<p class="card-text">Made in {{item.country_of_manufacture}}</p>
</div>
</div>
</div>
{% endfor %}
I cant get the first photo from "Album" to display. Nothing comes out. I've tried various things over three days, but with no success. Any help is greatly appreciated. Thank you.
Sincerely,
CKLee
As is explained in the documentation [Django-doc], you can use the url attribute of the value that is associated with the ImageField, so:
<img class="card-img-top" src="{{ item.album.photo_set.first.photo_identity.url }}" alt="">

django form processing and submit issues

New to Django.I retrieve data from mysql db that are displayed into a form.User needs to choose among the form choices. The view processes data that have been posted from the form by querying the DB and should send the results in csv format or in graph.I am trying right now to create a csv file with the results of the query but submit does not work.
views.py:
def monitor(request):
if request.method == 'POST' :
forms = ServicesForm(request.POST)
if forms.is_valid():
service = forms.cleaned_data['service']
scale = forms.cleaned_data['scale']
datatype = forms.cleaned_data['datatype']
starttime = forms.cleaned_data['starttime']
endtime = forms.cleaned_data['endtime']
id = Servicenames.objects.raw('SELECT id FROM servicenames WHERE servicename = ' + service )
# process and create query Select "dtime",datatype where "scale" = scale and "dtime' between starttime and endtime
# and service_id
servicestats = Servicestats.objects.raw('SELECT distinct dtime,'+ datatype + ' FROM servicestats WHERE scale = '+ scale + ' AND dtime between '+ starttime + ' and '+ endtime + 'and service_id = '+ id.id)
response = HttpResponse(mimetype='text/csv')
response['Content-Disposition'] = 'attachment;filename="export.csv"'
writer = csv.writer(response)
for s in servicestats:
writer.writerow([s.dtime,s.datatype])
return response
else:
forms = ServicesForm
return render_to_response('monitor/monitor.html', {'forms':forms},
context_instance = RequestContext(request))
models.py :
class Servicenames(models.Model):
id = models.IntegerField(primary_key=True)
servicename = models.CharField(unique=True, max_length=255)
class Meta:
db_table = u'servicenames'
def __unicode__(self):
return self.servicename
class Servicestats(models.Model):
# service_id = models.IntegerField(primary_key=True)
service_id = models.ForeignKey(Servicenames)
dtime = models.DateTimeField(primary_key=True)
scale = models.IntegerField(primary_key=True)
cnt = models.IntegerField()
min = models.FloatField()
max = models.FloatField()
avg = models.FloatField()
threenines = models.FloatField()
class Meta:
db_table = u'servicestats'
forms.py :
class ServicesForm(forms.Form):
services=Servicenames.objects.all()
service = forms.ModelMultipleChoiceField(queryset=services,widget=forms.Select(attrs={'class':'colr',}))
scales = Servicestats.objects.values_list('scale', flat=True).distinct()
scale = forms.ModelChoiceField(queryset=scales,widget=forms.Select(attrs={'onchange': 'this.form.submit();'}))
DATATYPE_CHOICES = (
('cnt', 'cnt'),
('min', 'min'),
('max', 'max'),
('avg', 'avg'),
('threenines','threenines'),
)
datatype = forms.ChoiceField(choices = DATATYPE_CHOICES,widget=forms.Select(attrs={'onchange': 'this.form.submit();'}))
starttime = forms.DateTimeField(initial = datetime.now)
endtime = forms.DateTimeField(initial = datetime.now)
template.html :
% extends "bbase.html" %}
{% block extrascripts %}
$("#monitor").addClass("active")
{% endblock %}
{% block content %}
<div class="main">
<p>Welcome to the monitoring management system.</p>
<p>Stay tuned for more details</p>
</div>
<div>{{forms.service}}<span id="selection"><--Select services</span></div>
<div>{{forms.scale}}<span id="selection"><--Select resolution</span></div>
<div>{{forms.datatype}}<span id="selection"><--Select data type</span></div>
<div>{{forms.starttime}}<span id="selection"><--Select start time</span></div>
<div>{{forms.endtime}}<span id="selection"><--Select end time</span></div>
<input type = "submit" value = "Submit">
{% endblock %}
Thanks for the help.
It seems you are missing a form tag around your form!
try
<form action='' method='post'>{% csrf_token %}
...your form html...
...inputs...
...submit...
</form>