Want to display an image - python

I am having a slight problem. I want a django app that can upload and display an image. Currently, it can upload the image but I cannnot display that image.
So for example, {{comment.photo}} will print out the path C:/Users/AQUIL/Desktop/myproject/images/P1000992.JPG. But I want to see that image on the screen. Not the path. How do I print out the image to the screen?
Here is some information that may help.
models.py
class Comment(models.Model):
name = models.CharField(max_length = 40)
datetime = models.DateTimeField(default=datetime.now)
photo = models.ImageField(upload_to='C:/Users/AQUIL/Desktop/myproject/media/images', blank=True, null=True)
note = models.TextField()
def __unicode__(self):
return unicode(self.name)
views.py
def home(request):
comments = None
try:
comments = Comment.objects.order_by('-datetime')
except:
return HttpResponseNotFound()
return render_to_response('home.html', {'comments':comments}, context_instance=RequestContext(request))
def add_notes(request):
comments = Comment.objects.all()
if request.method == 'POST':
form = CommentForm(request.POST or None, request.FILES)
if form.is_valid():
comments.datetime = datetime.now()
form.save(True)
return HttpResponseRedirect(reverse(home))
else:
form = CommentForm()
return render_to_response('form.html', {'form':form,'comments':comments}, context_instance = RequestContext(request))
home.html
{% extends "base.html" %}
{% block content %}
<H2>List of Comments</H2>
<div style="overflow:auto;padding: 10px; border:1px solid black; height:150px; width:700px;">
{% for comment in comments %}
{{comment.photo}} <br/>
<b>Posted by: {{ comment.name }} Date: {{ comment.datetime.date }} Time: {{comment.datetime.time}}</b><br/>
<div style="font-size:125%">{{ comment.note }}</div><br/>
{% endfor %}
</div>
{% endblock %}
form.html
{% extends "base.html" %}
{% block content %}
<h3>Add Notes</h3>
<form enctype="multipart/form-data" action="" method="POST">
{% csrf_token %}
<table>
{{form.as_table}}
<br/>
</table>
<input type="submit" value="Save" STYLE="background-color:#E8E8E8; color:#181818 "/>
</form>
{% endblock %}

{% if comment.photo %} <img src="{{ comment.photo.url }}" alt="Photo" /> {% endif %}
See Geoffrey's comment for how to upload the image correctly.

The upload parameter of ImageField must be a local path, so replace:
photo = models.ImageField(upload_to='C:/Users/AQUIL/Desktop/myproject/media/images', blank=True, null=True)
by:
photo = models.ImageField(upload_to='images', blank=True, null=True)
Then set the MEDIA_ROOT in settings.py as:
MEDIA_ROOT = 'C:/Users/AQUIL/Desktop/myproject/media/'
Finally your image 'myImage.png' will be accessible at:
C:/Users/AQUIL/Desktop/myproject/media/images/myImage.png
And this tag should load the image:
<img src="/media/images/myImage.png" alt=""/>
depends of your MEDIA_URL in settings.py which should be:
MEDIA_URL = '/media/'

Rather then {{comment.photo}}
use {{comment.photo.url}}
see sample in the docs

Related

Adding uploaded text file to textbox field - Django

I am pretty new to Django and still learning, but I am having a hard time trying to figure out how to let a user upload a .txt file but instead have the uploaded .txt file overwrite in the textfield itself.
Example: When uploaded https://imgur.com/a/jdCjlVS
I haven't been able to find understandable resources, but this is all I have at the moment:
forms.py
class NewInput(forms.Form):
text = forms.CharField(label='Input', max_length=1000, required=False)
file = forms.FileField(required=False)
models.py
class Collection(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="collection", null=True)
text = models.TextField(max_length=1000, default='')
create.html
{% extends 'main/base.html' %}
{% load crispy_forms_tags %}
{% block title %}
New Input
{% endblock %}
{% block content %}
<center>
<h3>Create a New Input:</h3>
<p class="text-primary"></p>
<form method = "post" action = "/create/" class="form-group" enctype="multipart/form-data">
{% csrf_token %}
{{form|crispy}}
<div class="input-group mb-3">
<div class="col text-center">
<button type="submit" name="save" class="btn btn-success">Create</button>
</div>
</div>
</form>
</center>
{% endblock %}
views.py
def create(response):
if response.user.is_authenticated:
username = response.user.username
if response.method == "POST":
form = NewInput(response.POST)
if form.is_valid():
n = form.cleaned_data["text"]
t = Collection(text=n)
t.save()
response.user.collection.add(t)
return HttpResponseRedirect("/collections/%s" % username)
else:
form = NewInput()
return render(response, "main/create.html", {"form": form})
else:
return HttpResponseRedirect("/login")
I tried adding a separate class as a form field but I was unable to figure out how to make it overwrite the text area instead.

How can I add a image on a post in django?

I want to create an upload image button in django admin post models. When an image is uploaded, will be nice to be displayed on both blog card and then on post detail on the website. Here is my code until now. How should I do this in order to make this work?
Here is my blog.html page
<div class="container">
<div class="row">
<!-- Blog Entries Column -->
<div class="column">
{% for post in post_list %}
<div class="card mb-4">
<div class="card-body">
<img class="card-image">{{post.header_image}}</img>
<h2 class="card-title">{{ post.title }}</h2>
<p class="card-text text-muted h6">{{ post.author }} | {{ post.created_on}} </p>
<p class="card-text">{{post.content|slice:":200"}}</p>
Află mai multe
</div>
</div>
{% endfor %}
</div>
</div>
</div>
Here is my post detail.html
<div class="container">
<div class="detail-row">
<div class="card-detail-body">
<h1> {{ post.title }} </h1>
<p class=" text-muted">{{ post.author }} | {{ post.created_on }}</p>
<p class="card-text ">{{ post.content | safe }}</p>
</div>
</div>
</div>
Here is models.py
from django.db import models
import datetime
from django.contrib.auth.models import User
STATUS = ((0, "Draft"), (1, "Published"))
class Post(models.Model):
title = models.CharField(max_length=1048)
slug = models.SlugField(max_length=1048)
author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='blog_posts')
related_name=('blog_posts')
content = models.TextField()
status = models.IntegerField(choices=STATUS, default=0)
created_on = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
And here are views.py
def blogPage(request):
floaterForm = FloaterForm()
post_list = Post.objects.all().order_by('-created_on')
context = {
'flForm' : floaterForm,
"post_list": post_list
}
return render(request, "blog.html", context)
def post_detail(request, pk):
post= Post.objects.get(pk=pk)
context = {
'post' : post
}
return render(request, "post_detail.html", context)
You've to create one field inside your models.py file like this
image = models.ImageField(upload_to="your_upload_dir_name")
then you've to set your media configuration now you can access your image inside your template like this
<img src="{{ post.image.url }}">
You firstly have to create the image field in Django. For example
blog_image = models.ImageField(upload_to="/media/blog_images")
#This /image/blog_images is the image directory.
It will save the image URL in the model field. Then you can use this image URL in the src of the image tag.
The html code should be like this.
<form method = "post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Upload</button>
</form>
And in the views, your code will be like this. You can change it according to your configuration.
if request.method == 'POST':
form = BlogsForm(request.POST, request.FILES)
if form.is_valid():
form.save()
Then you have to set the media configuration in your server configuration and in settings.py. I mostly use Nginx, so I do this.
#settings.py
MEDIA_ROOT = BASE_DIR / 'media'
MEDIA_URL = '/media/'
#ngnix
location /media {
autoindex on;
alias /path to media directory of project;
}
If still you got confuse, tell me in the comments. Thanks

Django form_valid() in CreateView not executing when trying to create a new dish object

In this code, the form_valid() function inside DishCreateView is not being executed when I try to create a new dish ie I am unable to create a new dish, when I click on create button page url not changes and remains the same. For detecting this I have put print statement inside form_valid() but this is not executed. Please help me out. Thanks
models.py
class Dish(models.Model):
name = models.CharField(max_length=100)
image = models.ImageField(upload_to='dishes_pics')
description = models.TextField()
ingredients = models.TextField(blank=True)
required_time_to_cook = models.CharField(max_length=100)
favourite = models.ManyToManyField(User, related_name='favourite', blank=True)
cuisine_id = models.ForeignKey(Cuisine, on_delete=models.CASCADE)
user_id = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('dish-detail', kwargs={'pk': self.pk})
def save(self):
super().save()
img = Image.open(self.image.path)
if img.height > 300 or img.width > 300:
output_size = (300,300)
img.thumbnail(output_size)
img.save(self.image.path)
views.py
class DishCreateView(LoginRequiredMixin,CreateView):
model = Dish
fields = ['name', 'image', 'description','required_time_to_cook','cuisine_id','user_id']
def form_valid(self, form):
form.instance.user_id = self.request.user
print('self==========form==create=====',form)
return super().form_valid(form)
form_template.html
{% extends "cookbook/base.html"%}
{% load crispy_forms_tags %}
{% block content %}
<div class="content-section">
<form method="POST">
{% csrf_token %}
<fieldset class="form-group">
<legend class="border-bottom mb-4">
Add Dish
</legend>
{{ form|crispy }}
</fieldset>
<div class="form-group">
<button class="btn btn-outline-info" type="submit">Create</button>
</div>
</form>
</div>
{% endblock content %}
dish_detail.html
{% extends 'cookbook/base.html' %}
{% load static %}
{% block content %}
<link rel="stylesheet" type="text/css" href="{% static 'cookbook/dish.css' %}">
<div class="media">
<img class="rounded-circle account-img" src="{{ object.image.url }}">
<div class="media-body">
<h2 class="account-heading">{{ object.name }}</h2>
<p class="text-secondary">{{ object.description }}</p>
<p class="text-secondary">{{ object.required_time_to_cook }}</p>
<p class="text-secondary"> {{object.cuisine_id}}</p>
</div>
</div>
{% endblock content %}
First thing i notice is that the name of the template is called form_template.html. Accourding the docs the createview uses a default suffix value for naming them template '_form' this in combination with you model name. So you should change your template name to:
from : form_template.html
to : dish_form.html
I think your view does not receive the data you post because the naming is not correct and you didn't add an action value to the form. This should not be problem if the naming matches the view.
If this still not fixes your problem step 2 would be to add a
def form_invalid(self, form):
print(form.errors)
to your view and put a print statement in there
this would give you the error back with the problem. so you know where the problem is.

Not Found: /products/images/DSroadmap.png Not Found: /products/images/codewall.jpg [26/Jan/2020 22:13:36]

I am unable to load images from my MEDIAL_URL on a html page. Below is my code for uploading images, media url and the html. Any any help will be highly appreciated.
html:
<div class="row">
{% for item in items %}
<div class='col-sm-3'>
{% for item in item.itemimage_set.all %}
{% if item.featured %}
<img src="{{ MEDIA_URL }}{{ item.image }}">
{% endif %}
{% endfor %}
{{ item.title }}
{{ item.price }}
</div>
{% cycle "" "" "" "</div><br/><hr/><div class='row'>" %}
{% endfor %}
</div>
model:
class ItemImage(models.Model):
item = models.ForeignKey(Item, on_delete=models.CASCADE)
image = models.ImageField(upload_to='products/images/')
featured = models.BooleanField(default=False)
thumbnail = models.BooleanField(default=False)
active = models.BooleanField(default=True)
updated = models.DateTimeField(auto_now_add=False, auto_now=True)
def __unicode__(self):
return self.item.title
media url & root:
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'static', 'media')
To access an image URL from a FileField() object, you need to access it via the .url property.
In this case, it would be item.image.url instead of item.image, which returns just the object (and not the URL you need).
Django docs: https://docs.djangoproject.com/en/3.0/ref/models/fields/#django.db.models.fields.files.FieldFile.url

Not sure how to see my search results for Django-haystack?

I recently set up django and haystack and I have no errors but How do I see my search results? It made no mention of setting up a view for it only a template and a url. The action in the form template is this
<form method="get" action=".">
that didn't work so I changed it to this
<form method="get" action="posts/search">
and I also tried this with the slash after search
<form method="get" action="posts/search/">
I also tried to give my url a name
url(r'^search/', include('haystack.urls'), name='search'),
and have the form like this
<form method="GET" action="{% url 'posts:search' %}">
when I tried it like that it gave me this error
django.core.urlresolvers.NoReverseMatch: Reverse for 'search' with arguments '()' and keyword arguments '{}' not found. 0 pattern(s) tried: []
how do I link my app properly to server so that the results display properly
heres my code
my form in my nav. the action is a page I had created before haystack the ones above are the new ones
<form method="GET" action="{% url 'posts:search-page' %}" class="navbar-form navbar-right" role="search">
<div>
<div class="input-group">
<input type="text" class="form-control" name="q" id="search" placeholder="search" value="{{ request.GET.q }}">
<span class="input-group-btn">
<button type="submit" class="btn btn-default">search</button>
</span>
</div><!-- /input-group -->
</div><!-- /.col-lg-6 -->
</form>
my posts/urls.py
from django.conf.urls import url, include
from .views import post_create, post_detail, post_list, post_update, post_delete, post_search, tag_list
urlpatterns = [
url(r'^$', post_list, name='list'),
url(r'^create/$', post_create, name='create'),
url(r'^search_results/$', post_search, name='search-page'),
url(r'^tag/(?P<slug>[\w-]+)/$', tag_list, name="tag_list"),
url(r'^(?P<slug>[\w-]+)/$', post_detail, name='detail'),
url(r'^(?P<slug>[\w-]+)/edit/$', post_update, name='update'),
url(r'^(?P<id>\d+)/delete/$', post_delete, name='delete'),
url(r'^search/', include('haystack.urls')),
]
my searche_indexes.py
from haystack import indexes
from .models import Post
class NoteIndex(indexes.SearchIndex, indexes.Indexable):
text = indexes.CharField(document=True, use_template=True)
title = indexes.CharField(model_attr='title')
publish = indexes.DateTimeField(model_attr='publish')
# content_auto = indexes.EdgeNgramField(model_attr='title')
def get_model(self):
return Post
def index_queryset(self, using=None):
"""Used when the entire index for model is updated."""
return self.get_model().objects.all()
my templates/search/search.html
{% extends 'base.html' %}
{% block content %}
<h2>Search</h2>
<form method="get" action=".">
<table>
{{ form.as_table }}
<tr>
<td> </td>
<td>
<input type="submit" value="Search">
</td>
</tr>
</table>
{% if query %}
<h3>Results</h3>
{% for result in page.object_list %}
<p>
{{ result.object.title }}
</p>
{% empty %}
<p>No results found.</p>
{% endfor %}
{% if page.has_previous or page.has_next %}
<div>
{% if page.has_previous %}{% endif %}« Previous{% if page.has_previous %}{% endif %}
|
{% if page.has_next %}{% endif %}Next »{% if page.has_next %}{% endif %}
</div>
{% endif %}
{% else %}
{# Show some example queries to run, maybe query syntax, something else? #}
{% endif %}
</form>
{% endblock %}
my post_text.txt
{{ object.title }}
{{ object.body }}
my Post model
class Post(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, default=1)
title = models.CharField(max_length=120)
slug = models.SlugField(max_length=200, unique=True)
image = models.ImageField(upload_to=upload_location,
null=True,
blank=True,
width_field="width_field",
height_field="height_field")
height_field = models.IntegerField(default=0)
width_field = models.IntegerField(default=0)
content = models.TextField()
draft = models.BooleanField(default=False)
publish = models.DateField(auto_now=False, auto_now_add=False)
timestamp = models.DateTimeField(auto_now=False, auto_now_add=True)
updated = models.DateTimeField(auto_now=True, auto_now_add=False)
tags = models.ManyToManyField(Tag)
objects = PostManager()
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse("posts:detail", kwargs={"slug": self.slug})
class Meta:
ordering = ["-timestamp", "-updated"]
as I said I got no system errors. This Is my 4th time attempting to use this. And Now there are no errors, Just some issue that has to do with displaying my results. Any guidance in the right direction is welcome

Categories