From the past 2 days i have literally lost my patience trying to make Cloudfiles work for my project(using cumulus). Here are some of the issues:
1.) Sometimes when i upload any photo using admin(creating a model and registering with admin)... the photo looks like its uploaded but when i try to either access it using a view function by Photo.objects.all() or even going to the cloudfiles control panel...the image simply doesnt open up. I get a resource not found. I check and double check if the region(chicago is default for me) settings is screwing with me....but i don't think so.
2.) I have used collectstatic method to successfully collect all static files in a container and i am able to successfully serve them. infact when i click the link(say for example) - http://ed770b871265201bf471-14f03984d90730040890dd30a2d85248.r68.cf2.rackcdn.com/admin/css/base.css
I am able to see the results and i am sure u can see it too.
But when i am trying to use them by STATIC_URL in my templates - The admin pages don't have their css working but my login/home pages are perfectly being rendered with my styles.
Here are my settings file/my view functions and anything that is important -
STATIC_ROOT = ''
STATIC_URL = 'http://ed770b871265201bf471-14f03984d90730040890dd30a2d85248.r68.cf2.rackcdn.com/'
STATICFILES_DIRS = (
os.path.join(PROJECT_DIR,'static'),
)
CUMULUS = {
'USERNAME': '***',
'API_KEY': '****',
'CONTAINER': 'photos',
'STATIC_CONTAINER':'static',
'SERVICENET': False, # whether to use rackspace's internal private network
'FILTER_LIST': [],
'TIMEOUT' : 60
}
DEFAULT_FILE_STORAGE = 'cumulus.storage.CloudFilesStorage'
STATICFILES_STORAGE = 'cumulus.storage.CloudFilesStaticStorage'
The model file part
class Photo(models.Model):
username = models.ForeignKey(User)
image = models.ImageField(upload_to='photos')
alt_text = models.CharField(max_length=255)
admin.site.register(Photo)
This is the view function as you requested kyle.
def profile_detail(request):
if request.user.is_authenticated():
username = request.user.get_username()
# userid = User.objects.get(username=username).values('__id')
userdetails = User.objects.filter(username=username)
photo = Photo.objects.get(username=request.user.id)
return render_to_response('profile_detail.html',{'userdetails':userdetails,'username':username,'photo':photo},
context_instance=RequestContext(request))
and the template for profile_detail -
{% extends 'profile.html' %}
{% load bootstrap_toolkit %}
{% block content %}
<img src="{{ photo.image.url }}" alt="{{ photo.alt_text }}" />
<br>
<p>{{ user.first_name }}</p>
<p>{{ user.last_name }}</p>
<p>{{ user.email }}</p>
{% endblock %}
I just now checked that i can view the image(No idea how) on the hosted site(production) but still can't do it in my dev environment.
Kyle can you please check if your testaccount has a picture of penguins in the 'MYProfile' page? :) Thanks for looking into it :)
The images are there, but possibly not where you expected them.
Link on your current site:
http://d12df125d01b8a258a3a-8112fdc02f7d385b44f56eb9e899d81c.r88.cf2.rackcdn.com/photos/Penguins.jpg
Where the image/file actually is:
http://d12df125d01b8a258a3a-8112fdc02f7d385b44f56eb9e899d81c.r88.cf2.rackcdn.com/photos%5CPenguins.jpg
The %5C is a \ rather than a /. This makes a difference as these are keys (key being the "path" and value being the file). You may want to check on how these were uploaded, and possibly normalize them to regular slashes (were these uploaded while you were on a Windows machine?).
Related
So I originally had the user create a post in admin and be able to leave image field blank and Django would set a default image.
My problem is;
If a user uploads an image, then deletes the image in admin, I get an error: The 'image' attribute has no file associated with it. when accessing solo.html in browser.
How can I make the default image reappear and specifically come from static folder?
My code:
settings.py
STATIC_URL = '/static/'
STATIC_DIRS = os.path.join(BASE_DIR, 'static')
models.py
# FIXME: If default image is changed to user's upload but then deleted. Make default image reappear.
# Recipe Field
class Recipe(models.Model):
title = models.CharField(max_length=200)
image = models.ImageField(upload_to='recipes/images/', blank=True)
def get_image(self):
if not self.image:
return f'{settings.STATIC_URL}default.png'
return self.image.url
solo.html
<h2>{{ recipe.title }}</h2>
<h3>{{ recipe.category }}</h3>
<h3>{{ recipe.meal }}</h3>
<img src="{{ recipe.image.url }}">
I'm just starting with Django so I apologize in advance if it's all a mess.
Thank you in advance!
What's happening is that the file itself is being deleted, but recipe.image is not being set to None.
I'm trying to send images in a letter, but it doesn’t work out for me. I tuned {{ STATIC_URL }} but it did not help... How i can fix this?
In settings: STATIC_URL = 'http://10.0.50.42:8103/static/'
In HTML: <img src="{{ STATIC_URL }}dc/images/banner2.png">
With this setting, I started to receive a letter, but the images are not displayed there.
First of all you have to load static files using below command as first line of html...
{% load static %}
then use static as below in your <img>...
<img src="{% static "dc/images/banner2.png" %}">
In my knowledge you cannot just put the link of image in the template that is rendered in the email and expect that it will work. As you are sending the image it still resides on your machine/server. The image must be saved as in, in a model and then you can you use that Model object to send as attachment.
Lets assume the file model is just below:
class ImageFile(models.Model):
file = models.ImageField(upload_to='Images',verbose_name='File Path', max_length=400, null=True)
and the send_mail function looks like:
def send_mail():
file_obj = ImageFile.objects.get(file='banner2.png')
file_url = file_obj.file.path
msg = EmailMessage(subject=subject, body=email_body, from_email=[frommail],
to=[tomail], bcc=[bcc mails])
msg.attach_file(file_url)
msg.send()
In all code snippets I see basic pattern of how filter is applied to an URL. For example,
<img src="{{obj.url|filter}}" />
I wonder how can I use filter with URL that consists of two parts?
<img src="{{something}}{{obj.url}}" />
Note: filter should deal with the complete URL, not just the second part of it
EDIT:
Model:
class Foo(models.Model):
token = models.CharField(max_length=150)
reference = models.ForeignKey(Reference)
View:
def index(request):
foos = Foo.objects.filter(reference=value).all()
return render(request, 'index.html', {'foos' : foos})
Template:
{% for foo in foos %}
<img id="foo_{{foo.pk}}" src="{{MEDIA_URL}}{{foo.token}}" />
{% endfor %}
As a matter of fact, I want to just apply easythumbnail URL filter to image URL, which has two parts.
If you're wanting to do things with context variables like this then you should make what you require available in the context rather than trying to manipulate things in the template.
Either add variable from your view or create a context processor if you have variables that you require in lots of places, because through a context processor you can create variables that are always available.
Check out this answer I wrote recently on this; https://stackoverflow.com/a/27797061/1199464
update following your comment
There's nothing wrong with writing a method on your model to format a string or similar;
class Foo(models.Model):
token = models.CharField(max_length=150)
reference = models.ForeignKey(Reference)
def get_url(self):
url = u'{media_url}{path}'.format(
media_url=settings.MEDIA_URL,
path=self.token
)
return url
Template:
{% for foo in foos %}
<img id="foo_{{ foo.pk }}" src="{{ foo.get_url }}" />
{% endfor %}
And on a sidenote if you're not too familiar with Django yet, you should use MEDIA_URL for user uploaded content and STATIC_URL for content that is yours. You can read more on these here; How can I get the MEDIA_URL from within a Django template?
Django docs; https://docs.djangoproject.com/en/1.7/ref/settings/#media-url
Can I use the Auth application's permission checking inside a template in Django? (I want to display a simple form at the end of the template for privileged users)
And more importantly, should I do it at all or is this no the "Django way"?
If you are looking to check for permissions in templates, the following code would suffice:
{% if perms.app_label.can_do_something %}
<form here>
{% endif %}
Where model refers to the model that the user need permissions to see the form for.
Refer to https://docs.djangoproject.com/en/stable/topics/auth/default/#permissions for more examples.
The currently logged-in user's permissions are stored in the template variable {{ perms }}
(This requires the following context processor to be enabled: django.contrib.auth.context_processors.auth)
Tested on Django 2.0 +
If you want to see all the permissions the logged in user has, on your template (.html),
print :
{{ perms.app_name }}
Or
{{ perms }}
In order to check if user has permission , use:
{% if perms.app_name.change_model_name_lower_cased %}
E.g :
{% if perms.Utilization.change_invoice %}
Here: Utilization is my App name. Invoice is a model name.
Note that in general, there will be 4 kinds of permissions:
change [E.g Utilization.change_projectemail]
view [E.g Utilization.view_invoice]
delete [E.g Utilization.delete_invoicetype]
add [E.g Utilization.add_invoicetype]
Also , if you want to see all permissions a user has due to the groups he belongs to, launch Django shell...
user = User.objects.get(username='somename')
user.get_group_permissions()
Here, all permissions listed, are due to the groups he belongs to.
One more Unique way to do this is:
{% if 'app_label.permission' in perms %}
<form here>
{% endif %}
Example:
{% if 'auth.view_group' in perms %}
<p> Hello World! </p>
{% endif %}
This comes handy when you want to use your default/custom authentication permissions whether you've created an app for your model or not because this method don't need an app name. It just need the permission name from your permissions table.
You can put multiple checks also using and/or commands:
{% if 'auth.view_group' in perms and 'auth.add_group' in perms %}
<form here>
{% endif %}
If you need more granularity in checking perms (on a particular object for example), check out this extension: http://django-authority.readthedocs.org/en/latest/check_templates/
And for those using Jinja templates and struggling with this question, like I did for a few hours/days...
Use an extended Jinja Environment, and add the request object to it:
# in settings.py
TEMPLATES = [
{
"BACKEND": "django.template.backends.jinja2.Jinja2",
'DIRS': ['jinja2'],
"APP_DIRS": True,
"OPTIONS": {
'environment': 'main.jinjaconfig.env.environment',
}
},
# Other template backends...
]
# main/jinjaconfig/env.py
from django.template.context_processors import request
from jinja2 import Environment
# ...
def environment(**options):
env = Environment(**options)
# Update globals with the functions and objects you need, here 'request'
env.globals.update({
'request': request,
# Other globals like 'static', 'url', ...
})
return env
Then you can access the request object in Jinja templates, and also request.user and request.user.has_perm() and all user related functions:
{% if request.user.has_perm('app_label.can_do_something') %}
{# Stuff .. #}
{% endif %}
I'm using django-imagekit to resize my user avatars and right now to display a default avatar (if the user didn't upload his/her avatar) I do this:
views.py
try:
usr_avatar = UsrAvatar.objects.get(user=request.user.id)
except UsrAvatar.DoesNotExist:
usr_avatar = UsrAvatar.objects.get(id='0')
template.html
<img src="{{ usr_avatar.avatar_image.url }}" >
This works fine but every time a user didn't upload his/her avatar I'm hitting the database for the default avatar image.
Is there a way to eliminate hitting the database when the user doesn't have an avatar image loaded by somehow attributing the default image link to usr_avatar or just doing something in the template.html? Thank you!
Apt username given your question!
You could create a context processor that provides the default avatar to every template and simply make sure that the context processor caches the image
settings.py
TEMPLATE_CONTEXT_PROCESSORS = (
...
'myapp.context_processors.default_avatar',
...
)
myapp/context_processors.py
from django.core.cache import cache
def default_avatar(request):
default_avatar = cache.get('default_avatar', False)
if not default_avatar:
default_avatar = UsrAvatar.object.get(id='0')
return {
'default_avatar' : default_avatar
}
Now the template variable 'default_avatar' is available in every template:
{% if usr_avatar %}
{{ usr_avatar }}
{% else %}
{{ default_avatar }}
{% endif %}
Alternatively just use the cache in your original query:
try:
usr_avatar = UsrAvatar.objects.get(user=request.user.id)
except UsrAvatar.DoesNotExist:
usr_avatar = cache.get('default_avatar', False)
if not usr_avatar:
usr_avatar = UsrAvatar.objects.get(id='0')
But Finally, it might be even better to avoid keeping the default avatar in the database at all and instead just write a context processor like above but instead of getting the default avatar from the DB, just have a static url to the image
from django.conf import settings
def default_avatar(request):
return {
'default_avatar' : '%simages/default_avatar.jpg' % settings.STATIC_URL
}