I've been trying to put a hyperlink on my image thumbnail which would take the user to a full size image. but I keep on getting an error.
here as it shows, scribblemedia is a ForeignKey to scribble
models.py
class ScribbleMedia(models.Model):
media = models.FileField(upload_to=get_file_path)
def __unicode__(self):
return self.media
def find_typecheck(self):
filename = self.media.name
try:
ext = filename.split('.')[-1]
imgcheck=['jpg','jpeg','png','gif','tiff','bmp']
if ext in imgcheck :
chk='image'
else:
chk='other'
except Exception:
chk='not supported'
return chk
class Scribble(models.Model):
title = models.CharField(max_length=120)
body = models.TextField()
user = models.ForeignKey(User)
media = models.ForeignKey(ScribbleMedia)
def __unicode__(self):
return u'%s, %s' % (self.user.username, self.media)
views.py
#login_required
def image_page(request,pk):
img=get_object_or_404(ScribbleMedia,pk=pk)
image=img.media
variables= RequestContext(request,{
'image': image
})
return render_to_response('image_page.html',variables)
urls.py
(r"^image/(\d+)/$", image_page),
image_page.html
{% if image %}
<img src= {{ image.url }} />
This is the page where the image thumbnail is available
scribble_page.html
{% if scribble.media.media %}
{% if scribble.media.find_typecheck == 'image' %}
{% thumbnail scribble.media.media.url "700x500" crop="center" as im %}
<img src="{{ im.url }}" width="{{ im.width }}" height="{{ im.height }}">
{% endthumbnail %}
{% else %}
do something else
{% endif %}
{% endif %}
It keeps on giving me the following error:
TemplateSyntaxError at /image/2/
Unclosed tag 'if'. Looking for one of: elif, else, endif
The if statements in your scribble_page.html are fine. You need to close your if block in your image_page.html template...
{% if image %}
<img src="{{ image.url }}" /> <!-- Also note the added quotations... -->
{% endif %} <!-- This is the line you need to add -->
Related
I am having an issue while implementing greater than operator in my template. I have a post in homepage which users can like and I have my friends' profile images displayed beside like count who like the post. Now if 10 friends like my post, i want only five of my friends' profile images to be displayed, and there will be a "+" at the end of displayed images. The "+" signifies that there are more friends who like my post. I tried this but it doesn't work:
Model:
class Profile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL,on_delete=models.CASCADE,blank=True,null=True)
profile_pic = models.ImageField(upload_to='ProfilePicture/', default="ProfilePicture/user-img.png", blank=True)
friends = models.ManyToManyField('Profile', related_name="my_friends",blank=True)
class Post(models.Model):
poster_profile = models.ForeignKey(settings.AUTH_USER_MODEL,on_delete=models.CASCADE, blank=True,null=True)
likes = models.ManyToManyField('Profile', related_name='image_likes', blank=True)
View:
def home(request):
#all post in homepage
posts = Post.objects.filter(poster_profile=request.user)
#Show friend who liked Post
friends_like_img = request.user.profile.friends.all().order_by('-id')
context = {'posts':posts,'friends_img':friends_img}
return render(request, 'template.html', context)
Template:
{% for post in posts %}
{% for img in friends_img %}
{% if img in post.likes.all > 20 %}
<img src="{{ img.profile_pic.url }}" height="25" width="25" alt="profile_pic">
{% else %}
<img src="{{ img.profile_pic.url }}" height="25" width="25" alt="profile_pic"> +
{% endif %}
{% endfor %}
{% endfor %}
Your code is a bit of a mess, but here are some pointers:
You only ever want five images, so take care of that in the view by slicing the queryset:
friends_like_img = request.user.profile.friends.all().order_by('-id')[:5]
Your template syntax is all off, you could do with reading the docs and getting used to some examples. In the context, you're using friends_img, not friends_like_img - the context is what the template cares about. Now, since we only ever have five images, we can do this in the template:
{% for img in friends_img %}
<img src="{{ img.profile_pic.url }}" ...>
{% endfor %}
{% if post.likes.count > 5 %}
+
{% endif %}
I am trying to display a file from a foreign key set of a model instance. The file can either be videos or pictures and is uploaded by users (think similar to Instagram). How can I display the file as <video> or <img> properly depending on the file type that was uploaded?
I am currently using <video> or <img> tags in html to show the file and they both work but only if the file is of the appropriate type. If the file is of the other type the incorrect tag will show a black box on the site.
{% if result.resultfile_set.all %}
{% for resultfile in result.resultfile_set.all %}
<video controls>
<source src="{{ resultfile.file.url }}">
</video>
<img src="{{ resultfile.file.url }}" />
<p>Caption: {{ resultfile.caption }}</p>
{% endfor %}
{% endif %}
Expected results are that if the file that has been uploaded by the user is a video file, display it as such; or if the file is an image file, display it as image. Instead I am currently only able to display both file types every time where one of them displays properly and the other displays as a black box
I would suggest checking the mime type (link.
Supposed you have a model called Media:
class Media(models.Model):
media = models.BinaryField(...)
def generate_html(self):
if mime_type(self.media) == "image":
return <img></img>
elif mime_type(self.media) == "video":
return <video></video>
else:
raise Exception("media type not understood")
Now you can use the generate_html method in your template
You can send type of media along with url and use conditional rendering to display appropriate media
{% if result.resultfile_set.all %}
{% for resultfile in result.resultfile_set.all %}
{% if resultfile.file.type == "video" %}
<video controls> <source src="{{ resultfile.file.url }}"> </video>
{% elif resultfile.file.type == "image"}
<img src="{{ resultfile.file.url }}" />
{% else %}
<div> Unsupported Media Format </div>
{% endif %}
<p>Caption: {{ resultfile.caption }}</p>
{% endfor %}
{% endif %}
Your result.resultfile_set.all will look something like
[{
file: {
type: "image",
url: "example.com/foo.png"
},
caption : "foo"
},
{
file: {
type: "video",
url: "example.com/bar.mp4"
},
caption : "bar"
}]
Don't worry, How can you display either a video or image file in a Django Template, I have answer for that
Use below code
{% for msg in post_user %}
{% if msg.p_image_path.url|slice:"-4:" == ".mp4" %}
#use video tag
{% else %}
#use image tag
{% endif %}
{% endfor %}
I tried a lot of methods finally the best solution is this:
models:
from mimetypes import guess_type
class Post(models.Model):
media = models.FileField()
def media_type_html(self):
"""
guess_type returns a tuple like (type, encoding) and we want to access
the type of media file in first index of tuple
"""
type_tuple = guess_type(self.media.url, strict=True)
if (type_tuple[0]).__contains__("image"):
return "image"
elif (type_tuple[0]).__contains__("video"):
return "video"
in templates you can access the type like this:
{% if post.media_type_html == "image" %}
<img src="{{ post.media.url }}">
{% elif post.media_type_html == "video" %}
<video controls>
<source src="{{ post.media.url }}">
</video>
{% endif %}
On the side of views.py, I get the external image url from the database and send it to template:
for variable in our_list:
thumbnail = ExternalAPICall(id=variable[0], 'thumbnail') #returns http://img48.imagesuit.gp/423ad3af.png
...
variable.append(thumbnail)
...
context = {
...
'our_list': our_list,
...
}
return render(request, 'index.html', context)
On the side of template I load thumbnail and decorate with thumbnail operator:
{% load thumbnail %}
...
{% for id, ... thumb ... in our_list %}
...
{% thumbnail thumb "100x100" crop="center" as im %}
<img alt="" src="{{ im.url }}" width="164" style="max-width:175px;border:0;min-height:auto;outline:none;text-decoration:none;vertical-align:bottom" class="CToWUd">
{% endthumbnail %}
{% endfor %}
And it renders empty line instead of the line of images.
What's wrong?
I can't get the image related value when I'm using {% for %} with the class Article. I tried with select_related, but I don't know how to define image to be correctly in displayed in the src="" attribute of my <img /> tag
Is there a clean way to make appear as I want?
models.py
class Image(models.Model):
gallery = models.ManyToManyField(Gallery)
name = models.CharField(max_length=100)
image = models.ImageField(upload_to='static/images/gallery')
def __str__(self):
return self.name
class Article(models.Model):
section = models.ForeignKey(Menu)
title = models.CharField(max_length=100)
text = models.TextField()
type = models.ForeignKey(Type)
image = models.ManyToManyField(Image)
def __str__(self):
return self.title
views.py
def index(request):
slider = Article.objects.all()
images = Image.objects.all()
return render(request, 'cms/index.html', locals())
template
{% for i in slider %}
<li>
<img src="{{i.image}}" alt="{{i.title}}"/>
<h2>{{i.title}}</h2>
<p>{{i.text}}, {{i.image_url}}</p>
</li>
{% endfor %}
You have to use 2 forloop for displaying images in manytomany table.
{% for i in slider %}
<li>
{% for im in i.image.all %}
<img src="{{im.image.url}}" alt="{{im.name}}"/>
{% endfor %}
<h2>{{i.title}}</h2>
<p>{{i.text}}, {{i.image_url}}</p>
</li>
{% endfor %}
Article.image is a ManyToMany field. Which image You want to display? First?
<img src="{{i.image.all.0.image.url}}" alt="{{i.title}}"/>
All?
{% for im in i.image.all %}
<img src="{{im.image.url}}" alt="{{im.name}}"/>
{% endfor %}
I want to save and filter users objects in my django app. After inputting the below codes, the imagefield keeps giving me a validation error, saying:
This field is required.
It’s pointing to the imagefield that I should fill it. How can I get rid of that error and make it filter?
Models
class Fin(models.Model):
user=models.ForeignKey(User)
title=models.CharField(max_length=250)
main_view=models.ImageField(upload_to="photos")
side_view=models.ImageField(upload_to="photos")
address=models.CharField(max_length=200)
city=models.CharField(max_length=200)
state=models.CharField(max_length=200)
guideline=models.TextField(max_length=1000)
def __unicode__(self):
return self.title
def get_absolute_url(self):
return self.title
class FinForm(ModelForm):
class Meta:
model=Fin
fields=('title','main_view','side_view', 'address','city','state','guideline')
exclude=('user')
Views
def fincrib(request):
extra_data_context={}
#if there's nothing in the field do nothing.
if request. method=="POST":
form =FinForm(request.POST)
if form.is_valid():
data=form.cleaned_data
newfincribs=Fin(
user= request.user,
title=data['title'],
main_view=Fin.objects.latest['main_view'],
side_view=Fin.objects.latest['side_view'],
address=data['address'],
city=data['city'],
state=data['state'],
guideline=data['guideline'])
newfincribs.save()
extra_data_context.update({'FinForm':form})
else:
form = FinForm()
extra_data_context.update({'FinForm':form})
extra_data_context.update({'Fins':Fin.objects.filter(user=request.user)})
plan=Fin.objects.filter(user=request.user)
paginator=Paginator(plan, 5)
try:
page=request.GET.get('page', '1')
except ValueError:
page=1
try:
Fins=paginator.page(page)
except (EmptyPage, InvalidPage):
Fins=paginator.page(paginator.num_pages)
extra_data_context.update({'Fins': Fins})
return render_to_response('post.html',extra_data_context,context_instance=RequestContext(request))
Template
{% block content %}
<form action="." method="POST">
{% csrf_token %}
<center> {{FinForm.as_p}} </center>
<input type="submit" value="Submit"/>
</form>
{% for Fin in Fins.object_list %}
<tr>
{{Fin.user}} </p> </strong>
<p>{{Fin.title}}</p>
<p><img src="{{MEDIA_URL}}/{{Fin.main_view}}"/></p>
<p> <img src="{{MEDIA_URL}}/{{Fin.side_view}}"/></p>
<p> {{Fin.address}} </p>
<p> {{Fin.city}}</p>
<p> {{Fin.state}}</p>
<p> {{Fin.guideline}}</p>
{% endfor %}
<div class="pagination">
<span class="step-links">
{% if Fins.has_previous %}
previous
{% endif %}
<span class="current">
Page {{ Fins.number }} of {{ Fins.paginator.num_pages }}
</span>
{% if Fins.has_next %}
next
{% endif %}
</span>
</div>
{% endblock %}
It's because by default all model fields are required, it means if you want to create and save new model instance in the database, you should fill all the mandatory fields. Maybe
main_view=Fin.objects.latest['main_view'],
side_view=Fin.objects.latest['side_view'],
is giving you the error, because there is no data.
change
main_view=models.ImageField(upload_to="photos")
side_view=models.ImageField(upload_to="photos")
to
main_view=models.ImageField(upload_to="photos", blank=True, null=True)
side_view=models.ImageField(upload_to="photos", blank=True, null=True)
btw, im not sure which django version you're using but your code is rather messy, any reason you're not using CBVs and static tags?