4

I am building a website with Django, hosted on PythonAnywhere. One of the website pages is a private page that I use to build content that will be then displayed in the public pages. Rather than saving the content produced within the private page to the database and then retrieving it from the database, I would like to save it to static files, in my static directory (it's a small number of JSON files that will be served over and over again, so I think it makes sense to serve them as static files).

In the view that defines my private page I have the following code for saving the file:

json=request.POST.get('json')
name=request.POST.get('name')
file=open(settings.STATIC_ROOT+'/'+name+'.json','w')
file.write(json)
file.close()

Note that I previously imported the settings:

from django.conf import settings

Strangely, this worked for a while, but then it stopped working. The error I get is:

Exception Value: 'function' object has no attribute 'STATIC_ROOT'

Am I doing something wrong? Is the fact that I am on PythonAnywhere relevant? Is it possible that the app is served by a worker that is not able to write to my static directory? What can I do to solve the problem?

user4422
  • 278
  • 3
  • 11
  • 1
    Prefer to use `os.path.join` in your `open` statement. Also, check the permissions in your folders. Does this work in your development machine? – Wtower May 23 '15 at 21:30
  • I am not using a development machine, I am working only online. What could be wrong with not using os.path.join? What permissions should the static folder have? – user4422 May 23 '15 at 21:35
  • You *should* use a development machine for a myriad reasons. `os.path.join` won't solve your issue but it is good practice: http://stackoverflow.com/questions/13944387/why-use-os-path-join-over-string-concatenation Regarding the permissions, normally it should have read-only but for your particular case obviously you require write permissions. – Wtower May 23 '15 at 21:47
  • The permissions are as follows: rwxrwxr-x – user4422 May 23 '15 at 22:23
  • Static files are made to **static**. Why don't upload to media folder? – sobolevn May 24 '15 at 08:34
  • 1
    PythonAnywhere dev here -- that certainly all sounds like it should work. Your app is served by a worker running as your own user ID, so it should have permissions to write to the directory. – Giles Thomas May 24 '15 at 20:20
  • 2
    Just noticed -- `Exception Value: 'function' object has no attribute 'STATIC_ROOT'` suggests that the variable `settings` in your call to `open` has been replaced by a function. Do you have any code that defines a function called `settings` in between the import and the open? – Giles Thomas May 24 '15 at 20:21
  • That was the problem. I had a view that was also named settings, which created the conflict. I am now going to post the proposed solution, which seems to work. – user4422 May 24 '15 at 20:58

1 Answers1

3

As pointed out by PythonAnywhere staff, the procedure was legitimate and supposed to work because the app is served by a worker running as my own user ID which has permissions to write to the static directory. The problem was generated by a naming conflict due to the fact that also one of the views had been named settings. To solve the problem I substituted the import statement with

from django.conf import settings as django_settings
import os

and the open statement with

file=open(os.path.join(django_settings.STATIC_ROOT, f'game_{name}.json'),'w')

After doing these substitutions, everything seemed to work.

user4422
  • 278
  • 3
  • 11
  • In my case I have an error FileNotFoundError: [Errno 2] No such file or directory when I use your code. Please any solution to it. – GSandro_Strongs May 19 '21 at 23:05