1

I am using Django 1.11 in my application.

I've implemented the authentication using django-registration and created a profile model to store some user infos:

class Profile(models.Model):
    ...
    user = models.OneToOneField(User)
    nick = models.CharField(max_length=50)
    level = models.PositiveIntegerField(null=True)
    avatar = models.CharField(max_length=500, null=True, blank=True)
    ...

This model is being created/saved with signals:

def create_user_profile(sender, instance, created, **kwargs):
    if created:
        Profile.objects.create(user=instance)


def save_user_profile(sender, instance, **kwargs):
    instance.profile.save()

post_save.connect(create_user_profile, sender=User)
post_save.connect(save_user_profile, sender=User)

Well, I am not allowing users to upload images, as you see. The workflow of choosing an avatar image is:

  1. User access profile configuration page
  2. This page has a button that opens a modal with image options, the user has to choose one.
  3. User select an image.
  4. User click to save changes.

What I am saving at profile's avatar field is a string that have to be concatenate to the static url, for instance, if the image path is:

127.0.0.1:8000/static/account_settings/avatar-images/man2.jpeg

I am saving:

account_settings/avatar-images/man2.jpeg

I've being through this workflow in production with debug set to True (impossible to make with debug = False because of the error 500). So, I've opened the user public profile page and it gives me the same error.

But I've found the root of the problem in this template:

{% if public_user.profile.avatar %}
    <img class="img-fluid w-100 u-block-hover__main--zoom-v1" src="{% static public_user.profile.avatar %}" alt="User Avatar Image">
{% else %}
    <img class="img-fluid w-100 u-block-hover__main--zoom-v1" src="{% static 'assets/img/tmp/avatar.jpg' %}" alt="User Avatar Image">
{% endif %}

If exist something in public_user.profile.avatar, I have the error 500. But if the profile has no image, it works fine. I don't know why this code doesn't work:

{% static public_user.profile.avatar %}

Any ideia why the result of this code is getting me error?

Error log:

2018-01-10T13:53:05.153051+00:00 app[web.1]:     url = self.url(context)
2018-01-10T13:53:05.153052+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.6/site-packages/django/templatetags/static.py", line 102, in url
2018-01-10T13:53:05.153053+00:00 app[web.1]:     return self.handle_simple(path)
2018-01-10T13:53:05.153053+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.6/site-packages/django/templatetags/static.py", line 117, in handle_simple
2018-01-10T13:53:05.153054+00:00 app[web.1]:     return staticfiles_storage.url(path)
2018-01-10T13:53:05.153055+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.6/site-packages/django/contrib/staticfiles/storage.py", line 162, in url
2018-01-10T13:53:05.153055+00:00 app[web.1]:     return self._url(self.stored_name, name, force)
2018-01-10T13:53:05.153056+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.6/site-packages/django/contrib/staticfiles/storage.py", line 141, in _url
2018-01-10T13:53:05.153057+00:00 app[web.1]:     hashed_name = hashed_name_func(*args)
2018-01-10T13:53:05.153057+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.6/site-packages/django/contrib/staticfiles/storage.py", line 432, in stored_name
2018-01-10T13:53:05.153063+00:00 app[web.1]:     raise ValueError("Missing staticfiles manifest entry for '%s'" % clean_name)
2018-01-10T13:53:05.153064+00:00 app[web.1]: ValueError: Missing staticfiles manifest entry for 'account_settings/avatar-images/man2.674506bb8a45.jpeg'
B. Almeida
  • 377
  • 1
  • 11
  • 1
    If you're getting a 500, there is almost definitely an error in the logs. Please post that here as well. – wholevinski Jan 10 '18 at 13:06
  • There are some things that Django only allows you to do when debug is enabled, for security purposes. I would review your settings. It may also help if you try to setup logging so you can see the actual error. – sytech Jan 10 '18 at 13:06
  • @wholevinski In the logs that I've accessed using "heroku logs" there's just a line with the error code and the GET request that was done. I am trying to find a way to get a detailed log and I will update my question with it as soon as possible – B. Almeida Jan 10 '18 at 13:31
  • 1
    Hm, ok. It looks like Heroku expects a stream logger. So, put this in your config file: ```LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'handlers': { 'console': { 'class': 'logging.StreamHandler', }, }, 'loggers': { 'django': { 'handlers': ['console'], 'level': 'DEBUG' } } }``` After that, you _should_ get a lot more logging from running `heroku logs` – wholevinski Jan 10 '18 at 13:37
  • @wholevinski thanks! the log was too long, I think just the last lines will be enough, tell me if I am wrong that I fix it. – B. Almeida Jan 10 '18 at 13:58
  • It looks like `account_settings/avatar-images/man2.674506bb8a45.jpeg` isn't matching what you actually have saved off: `account_settings/avatar-images/man2.jpeg`. Maybe try removing the `{% static %}` directive and just put it in `{{ public_user.profile.avatar }}` instead. It's attempting to look up the hash named value. – wholevinski Jan 10 '18 at 15:26
  • 1
    Actually, check your settings file as well. See if you have `STATICFILES_STORAGE` set to `ManifestStaticFilesStorage`. If so, comment out that line to see if that fixes it. Check this thread out: https://stackoverflow.com/a/34586172/769971 – wholevinski Jan 10 '18 at 15:31
  • I have in my code STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage' – B. Almeida Jan 10 '18 at 15:34
  • Try commenting that out and see if that fixes it. If so, and you want to continue using whitenoise, you can turn on auto refresh it seems: http://whitenoise.evans.io/en/stable/django.html#WHITENOISE_AUTOREFRESH It says not to use that in production, but I have no experience with white noise and no idea why. – wholevinski Jan 10 '18 at 15:36

3 Answers3

2

I've figured out what was the problem after seing the detailed logs that wholevinski helped me finding with his comments plus his assistance. I don't like to answer my own questions, but I'll do it here to keep a record of how I solved the problem.

Well, what is happening is that I am using WhiteNoise to serve my static files and it's compressing my static files to be able to have cache support.

In my code I have:

STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'

The following line in my code makes whitenoise create file versions with the md5 hash of the file content appended to the original file name, so for instance, "filename.jpeg" generates a file "filename.674506bb8a45.jpeg" that will be served to the user. If the server file is different from what is being cached in the user browser, so the md5 will be different and the new file will be served to the user.

The problem was that I was getting the image filename via javascript and it was saving in my database:

account_settings/avatar-images/man2.674506bb8a45.jpeg

instead of

account_settings/avatar-images/man2.jpeg

What I did to solve the problem was change my javascript to ignore the md5 version. Now I am saving account_settings/avatar-images/man2.jpeg and the problem is gone.

B. Almeida
  • 377
  • 1
  • 11
0

Try to add the admin email to your setting, this will provide you a way to determine what is the error message when error 500 occurs

SERVER_EMAIL = 'ur@from-email-address.com' ADMINS = ( ('Exceptions Email', 'destination@email.com'), )

you might need to setup smtp setting as well

Du D.
  • 5,062
  • 2
  • 29
  • 34
0

Try this

{% if public_user.profile.avatar %}
    {% with public_user.profile.avatar as img_url %}
    <img class="img-fluid w-100 u-block-hover__main--zoom-v1" src="{% static img_url %}" alt="User Avatar Image">
    {% endwith %}
{% else %}
    <img class="img-fluid w-100 u-block-hover__main--zoom-v1" src="{% static 'assets/img/tmp/avatar.jpg' %}" alt="User Avatar Image">
{% endif %}
itzMEonTV
  • 19,851
  • 4
  • 39
  • 49