Emulate DirectoryIndex in Django dev server - django

I'm able to configure a new Django project to serve static files. This is the project layout:
.
├── __init__.py
├── manage.py
├── settings.py
├── mystatic
│   └── index.html
└── urls.py
settings.py:
STATICFILES_DIRS = (
join(abspath(dirname(__file__)), 'mystatic'),
)
I run the server the usual way:
./manage.py runserver
This works pretty well. At http://127.0.0.1:8000/static/index.html it shows my custom index page. What I'd like to do is access to http://127.0.0.1:8000/static/ (with or without trailing slash) and get the same page. Instead the server doesn't respond with my own page, but with the default Django project page (It worked! Congratulations on your first Django-powered page. etc.).
How should I change things (maybe in urls.py or in some view), so that even if without specifying index.html both the URLs give the page I want? Using plain Apache this is the default behavior, because when a page name is not specified index.html is used (see Apache's DirectoryIndex). I need to replicate the same on Django development server.

Related

Folder structure for React and Django REST

I'm in the process of refactoring a rather basic/traditional Django webapp to a more modern React-plus-Django-REST setup. I'm far more familiar with Django than React, so where to put the React part is what's confusing to me.
My question is: what are the best practices for folder structure in using both Django and React? Ideas I've had:
Put all React files in their own folder like this:
.
├── app1
│   └── example-files.py
├── app2
│   └── example-files.py
├── manage.py
├── react-django-project
│   ├── settings.py
│   └── urls.py
├── requirements.txt
├── some-app-1
│   └── example-files.py
├── some-app-2
│   └── example-files.py
├── src
│   └── components
│   ├── component1.js
│   └── component2.js
└── ...
Put all React files in the static folder, but this doesn't seem right to me.
Is there an established set of best practices for this?
Most of the time there are two separate projects for the back and the front end:
To build a ReST API using Django I'd strongly recommend you to check out Django REST framework if you haven't already. There is a simple tutorial on that home page that should get you up and running.
For the React app "React Create App" seems to be the standard way to start a project nowadays. See the linked GitHub page for step-by-step instructions.
Then follow this "Proxying API Requests in Development" guide to proxy requests to your API for your development setup.
I agree with Igonato about having separate projects for frontend and backend. As client(Frontend) would make Ajax(API) calls to the server(Backend) and with the response data, client renders the page.
Especially with react, you need to convert the react code to minified js and css for higher performance on the production server.
You may use djangorestframework in the backend and setup a django server. For frontend, here are a couple of options:
1. you can use dva (if you intend to use redux). dva is good. I would recommend not to use redux until the state management in your application gets complicated.
2. If you are not gonna use redux, then you can use create-react-app
For front-end I would recommend to use antd if you want to go for material design based application. It's quite a lot of UI elements that you would need in your application. It's battle tested. I have used it in ~9 applications, I have made in the past 6 months.
As the others mentioned, using different repositories is the common approach to solve this. However for a smaller team / smaller project a single repository should suffice.
To keep everything in one repo you create a separate for folder for the react app, usually I name it projectname-client. If you are using create-react-app you could serve the index.html from the build folder by adding that path to settings file.
# settings.py
# Path to the frontend app build directory
BUILD_DIR = os.path.join(BASE_DIR, '{{ project_name }}-client/build')
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
BUILD_DIR
],
...
},
]
STATICFILES_DIRS = [
os.path.join(BUILD_DIR, 'static'),
]
# urls.py
urlpatterns = [
...
path('', TemplateView.as_view(template_name='index.html'), name='index'),
]
If you are interested, I'm working on a django-admin startproject template that sets up the project to work with create-react-app. You can take a look here.

Django 1.10 is not detecting changes in my models, and won't create migrations

I'm just getting started with Django. I like to hack at things, so alongside the polls tutorial I'm also building my own experimental application. It has come to pass that I want to change the name of the experimental application and its associated project.
In the course of working on that, I decided to drop my current database and start over fresh. Something went wrong, I can't remember what. It's been several hours now, making progress here, googling that there.
The situation I now seem to be in is that Django refuses to notice changes in my models.py. Currently, there are no migrations listed for the app when I run manage.py showmigrations, although the app is itself listed.
I have tried deleting the migrations directory, changing the contents of the models.py file, and combinations thereof, and also trying out various manage.py commands that looked promising. So far, nothing has worked.
So, what might I be doing wrong? Remember that I have changed the name of the app, which includes changing the name of directory it is stored in, as well as the name of the database. Search and replace has been performed on the files in the project and app. settings.py has been pored over, but everything I know about seems to match up fine.
Thanks!
I assume you have changed your app name in your settings.py? And when you say you changed your app name, did you start a new app or a new project... meaning, when you start you do this:
django-admin.py startproject myproject
Running startproject gives you the following folder and file structure:
├── manage.py
└── myproject
├── __init__.py
├── settings.py
├── urls.py
└── wsgi.py
From there, you can run
python manage.py startapp myapp
This will make your folder structure look like this:
├── manage.py
├── my_django15_project
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
└── myapp
├── __init__.py
├── models.py
├── tests.py
└── views.py
From there, you could change your app by changing the folder name 'myapp' to 'mynewapp' and then by modifying your settings.py to have 'mynewapp' listed in your INSTALLED_APPS section.
After doing this you should run
pythonmanage.py makemigrations mynewapp
Verify that it makes the migration files
then run
python manage.py migrate
If you changed the folder myproject to a new name, such as mynewproject, I would suggest to try changing it's name back, then running
django-admin.py startproject mynewproject
then after you do that, update those files accordingly, and copy your myapp folder into the mynewproject folder.
Some other things you may want to check are that your database connectors are correct, and also try restarting your webserver.
If none of this works, you will need to give me some more information, so leave me a comment and let me know
Good Luck

CommandError: You must set settings.ALLOWED_HOSTS if DEBUG is False

I'm using Django 1.6.5 with the setting:
DEBUG = True
When I change to DEBUG = False and run manage.py runserver, I get the following error:
CommandError: You must set settings.ALLOWED_HOSTS if DEBUG is False
I get the same error with the following setting:
ALLOWED_HOSTS = ['127.0.0.1', 'localhost']
How can I fix this?
Try
ALLOWED_HOSTS = ['*']
Less secure if you're not firewalled off or on a public LAN, but it's what I use and it works.
EDIT: Interestingly enough I've been needing to add this to a few of my 1.8 projects even when DEBUG = True. Very unsure why.
EDIT: This is due to a Django security update as mentioned in my comment.
Your solution might be to add the original IP and/or hostname also:
ALLOWED_HOSTS = [
'localhost',
'127.0.0.1',
'111.222.333.444',
'mywebsite.example']
The condition to be satisfied is that the host header (or X-Forwarded-Host if USE_X_FORWARDED_HOST is enabled) should match one of the values in ALLOWED_HOSTS.
Make sure it's not redefined again lower down in your settings.py. The default settings has:
ALLOWED_HOSTS = []
From documentation:
https://docs.djangoproject.com/en/1.10/ref/settings/
if DEBUG is False, you also need to properly set the ALLOWED_HOSTS
setting. Failing to do so will result in all requests being returned
as “Bad Request (400)”.
And from here:
https://docs.djangoproject.com/en/1.10/ref/settings/#std:setting-ALLOWED_HOSTS
I am using something like this:
ALLOWED_HOSTS = ['localhost', '127.0.0.1', 'www.mysite.com']
Use this:
ALLOWED_HOSTS = ['localhost', '127.0.0.1']
If you work in PyCharm, check the Environmental variables for your Django server. You should specify the proper module.settings file
This works for me:
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False
ALLOWED_HOSTS = ['localhost', '127.0.0.1']
If you are using PyCharm
This solution applies only if you are using a different settings.py and have environment variables set
I had the same issue, but in my case the issue was, I was using a different settings.py file than the default (and had commented out my whole original settings.py), though I had it properly configured in my manage.py but in PyCharm I had to configure it as well in my Environment Variables via:
Edit Run Configurations >> Environment Variables
In my case I had split out my settings.py into base.py and development.py in a settings folder. It looked something like:
<name-of-your-project-app>/
├── __init__.py
├── asgi.py
├── settings
│   ├── __init__.py
│   ├── base.py
│   └── development.py
├── urls.py
└── wsgi.py
The problem was much bigger than ALLOWED_HOSTS=... because none of the settings were recognized by python manage.py runserver.
The fix was to configure the DJANGO_SETTINGS_MODULE by running
export DJANGO_SETTINGS_MODULE=decoupled_dj.settings.development
in the command line. I think this tells Django, 'Hey look for my settings in the development.py'
Try
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = ['*']
A value of '*' will match anything; in this case you are responsible to provide your own validation of the Host header.
I had set ALLOW_HOSTS, INTERNAL_IPS and DEBUG=TRUE
but still got this error.
my problem was i had created a python package which its name
was 'settings' in main app.
and that package name interfered with 'settings.py' file.
I also experienced the same error and found it is happening due to settings file configuration change. You have to configured few things as below mentioned.
Try
In settings.py
ALLOWED_HOSTS = ['*']
In manage.py
def main():
"""Run administrative tasks."""
os.environ.setdefault('DJANGO_SETTINGS_MODULE', '<your-project-name>.settings')
In asgi.py
os.environ.setdefault('DJANGO_SETTINGS_MODULE', '<your-project-name>.settings')
In wsgi.py
os.environ.setdefault('DJANGO_SETTINGS_MODULE', '<your-project-name>.settings')
So in my main directory in my django project, I had a two directories that had the same name so I deleted the settings folder I had and kept the settings.py file that comes with django.
What I had originally
<name-of-your-project-app>/
├── __init__.py
├── asgi.py
├── settings
│ ├── __init__.py
│ ├── base.py
│ └── development.py
├── settings.py
├── urls.py
└── wsgi.py
What I had afterwards
<name-of-your-project-app>/
├── __init__.py
├── asgi.py
├── settings.py
├── urls.py
└── wsgi.py
Make sure the name of the directory is the same that you are mentioning in the INSTALLED_APPS. These are the solution to errors sometimes.
Faced the same error when using a .env file in development in a local setup on my computer which I didn't copy on the production server. As soon as I added the .env file on the production server the error was resolved. I have also added the server's IP Address to the allowed_hosts list on the settings file.
I also experienced this cmderror. After trying all the answers on here, I couldn't still figure out the problem, here is what I did:
Cd into the project directory. e.g cd project-dir
I migrated. e.g python manage.py migrate
I created a super user. e.g python manage.py createsuperuser
Enter the desired info like username, password, email etc
You should get a "super user created successfully" response
Now run the server. E.g python manage.py runserver
Click on the URL displayed
The URL on your browser should look like this, 127.0.0.1:8000/Quit
Now edit the URL on your browser to this, 127.0.0.1:8000/admin
You should see an administrative login page
Login with the super user info you created earlier on
You should be logged in to the Django administration
Now click on "view site" at the top of the page
You should see a page which shows "the install worked successfully..... Debug = True"
Voila! your server is up and running
Just simply comment out the line: ALLOWED_HOSTS = [...]

What good way for structure of project and owners of dirs in django?

Imagine that my django project contain few apps. On server it located at /var/www/ProjectName dir. My username is Foo and sometimes i want edit file of server. Which best solution for next questions?
What owner of /var/www?
What owner of /var/www/ProjectName?
What apache process owner?
Where locate static files (css, js)? Is it from all apps in one dir or different dirs for different apps? What Owner of this dir?
Where locate media files (with upload users)? Is it from all apps in one dir or different dirs for different apps? What Owner of this dir?
What owner of py and pyc files, dirs of apps?
PS. Maybe project is located at my home directory?
I have some suggestions about that, but I would like to hear more experienced people.
on ubuntu 12.04 root
drwxr-xr-x 3 root root 4096 Nov 8 11:59 www
cd /var/www && ls -la to see owner, probably root?
www-data, on 12.04 www-data homes directory is /var/www (www-data:x:33:33:www-data:/var/www)
you can collectstatic to whatever directory you want in your project. I often have a directory called static next to manage.py. The owner is probably the same as the owner of your django project. You only need to allow read access to this folder for apache
You will probably want to consider a centralized media folder, instead of having media for each app. For both static and media you can fairly easily upload everything to s3 using django-storages
the owner can be anyone you want, I can't say the owner because it is your machine. But, I think, the webserver will need to execute the py files, so you can change your permissions to allow for this.
You can locate the project whereever you want. In apache virtual host you give the location of your wsgi file. There is no reason your project must live in /var/www
Here is the structure I'm using.
django/
├── project_virtualenv (virtualenv folder)
└── versioned (folder for things that are versioned)
├── devdoc (documentation)
└── py (code)
└── project (django project)
├── django_app (django app)
│  
├── project (project folder)
   ├── files
   │   ├── media (media, user uploads, etc)
   │   ├── production_static (statics for production)
   │   └── static (statics for development)
   └── templates
  
The directory django is located in the home directory on the production server, only the wsgi.py is in the publicly available folder (in my case /home/user/public_html/wsgi.
I've chmoded everything in the Django folder to 777 just to get everything working on the testing production server. Not sure what are the security risks, even dough the files aren't directly served.

Deploy Django project: folder/project structure

My django project in eclipse has this project structure:
main-project-folder/
src/
main-app/
app1/
app2/
settings.py
manage.py
urls.py
__init__.py
media/
templates/
Can i deploy the project with this structure? In other words, is right way to put src and other folders (media, tempaltes, etc.) in the root folder of my server (where my domain is linked)?
Like:
my-server-folder/
src/
media/
...
I imagine that in my-server-folder i should put the entry point of project, but in my project i haven't an entry point in main-project-folder, or does django automatically redirect to an entry point of src/main-app folder (i think that it doesn't because i don't find any options that say to django to do it)?
Sure. That's a fine directory structure.
Keep in mind your web server isn't going to know what to do with the Django project unless you tell it. If your web server is Apache (which it probably is if you don't know) look here for instructions to set it up to run the Django app:
https://docs.djangoproject.com/en/dev/howto/deployment/wsgi/modwsgi/
And here for WSGI:
http://code.google.com/p/modwsgi/wiki/IntegrationWithDjango
Django apps aren't like PHP where you just upload them to the web server and they work.