Django tutorial 1 not showing polls - django

I am taking a test Driven Development course for python (which is awesome) Obeythetestinggoat and so my Django needs work. So I'm taking the Djangoproject.com course and I get all the code entered and the server runs but the polls won't change.
The home page http://127.0.0.1:8000 shows
"It worked!
Congratulations on your first Django-powered page."
Which is great but it won't show the polls or the admin buttons and I've run out of ideas on how to redirect it but not sure the problem.
from django.conf.urls import include, url
from django.contrib import admin
urlpatterns = [
url(r'^polls/', include('polls.urls')),
url(r'^admin/', admin.site.urls),
]
I'm rather proud that I figured out the server and other areas but I just don't know what I am missing to get the page to show the polls.
https://docs.djangoproject.com/en/1.10/intro/tutorial01/

Yes, all you need to do is go to http://127.0.0.1:8000/polls/ . Otherwise if you want put your default polls page on the home page like you intended to do in http://127.0.0.1:8000/
you could do this in your urls.py
from django.conf.urls import include, url
from django.contrib import admin
urlpatterns = [
url(r'^$', include('polls.urls')),
url(r'^admin/', admin.site.urls),
]
hope it helps.

http://127.0.0.1:8000 is the main page of your preoject, but in the urls, you define (with regex) how to manage requests to http://127.0.0.1:8000/polls/ and http://127.0.0.1:8000/admin/. You should visit those URLs.

There's a urls.py at the wrong place made by the django-admin startproject mysite command.
.
├── db.sqlite3
├── manage.py
├── mysite
│   ├── asgi.py
│   .
│   .
│   │
│   ├── urls.py <-- right place
│   └── wsgi.py
├── polls
│   .
│   .
│   ├── urls.py
│   └── views.py
└── urls.py <-- wrong place
If you forget to remove it, and keep it, while creating the right one at the right place, it prevents the rules of the right one to be applied.

Related

Django URL patterns to serve external webpack bundle

I'm writing a django rest framework API (backend) with a react SPA frontend. For the production environment, the front end is served up via nginx at http://example.com/ and the backend is proxied to gunicorn and served from the same domain with a different path - http://example.com/api/
This is all working fine in production, there are no CORS issues as the frontend and backend are both served up under the same domain via nginx.
For local development, I want to be able to replicate a similar setup using ./manage.py runserver and have django serve up the frontend from project/frontend/dist (built by npm build seperately).
Has anyone got any urlpattern wizardry that will allow this to happen and also let the react-router play nicely? I just can't figure it out and it's starting to drive me nuts...
The project structure is something like this if it helps in any explanations.
Project
|
── backend
│   ├── apps
│   ├── config
| | ├── settings.py
| | ├── settings_local.py
| | ├── urls.py
│   ├── manage.py
│   ├── requirements.txt
│   └── venv
├── frontend
│   ├── dist (contains the npm build webpack)
│   ├── node_modules
│   ├── package.json
│   ├── package-lock.json
│   ├── scripts
│   ├── src
│   ├── webpack.config.js
Edit #1
Thanks to another post I was able to get partially the way there by adding this to my urls.py
if settings.DEBUG:
from django.views.generic import RedirectView
from django.contrib.staticfiles.views import serve
bundle_path = os.path.abspath(os.path.join(root_dir, 'frontend', 'dist'))
settings.STATICFILES_DIRS += (bundle_path,)
urlpatterns += [url(r'^$', serve, kwargs={'path': 'index.html'})]
urlpatterns += [url(r'^(?!/?static/)(?!/?media/)(?P<path>.*\..*)$',
RedirectView.as_view(url='/static/%(path)s', permanent=False))]
The only issue I have here is that if I go directly to one of the JS router links, then django tries to interpret it and can't find the route.
What I need now is a catch-all that will redirect to '/' but also keep any extra URL path information on the url
Finally got this to work with all the routing.
Added the webpack dist folder to settings.STATICFILES_DIRS
Added the webpack frontend path to settings.TEMPLATES
Added 3 new urlpatterns to urls.py ( based on a conditional, settings.DEBUG)
urlpatterns += [
url(r'^(?!/?static/)(?!/?media/)(?P<path>.*\..*)$',
RedirectView.as_view(url='/static/%(path)s', permanent=False)),
url(r'^$', TemplateView.as_view(template_name='dist/index.html'), name='frontend'),
url(r'^(?P<path>.*)/$', TemplateView.as_view(template_name='dist/index.html'), name='frontend'),
]
The first redirects any of the asssets for the bundle to be served using django's static files.
The second pattern serves the root path / as a template from the webpack dist folder
The final piece handles all the leftover JS routing paths to go back to the initial root view.
You can use nginx reverse proxy to serve them.
No need config Django's url.
See example here:
http://www.codingpedia.org/ama/how-to-configure-nginx-in-production-to-serve-angular-app-and-reverse-proxy-nodejs

Django include within single urls.py

I want to make an include in my urls.py referring to another urls in the same urls.py file.
My structure is as follows:
├── docs
├── requirements
├── scripts
└── sonata
├── person
│   ├── migrations
│   ├── templatetags
│   └── urls.py
├── registration
│   ├── migrations
│   └── urls.py
└── sonata
├── settings
└── urls.py
And I want every coming url with prefix 'pdf/' to add a value to kwargs and calling again the rest of url. This is my attempt:
urlpatterns = patterns('',
url(r'^$',TemplateView.as_view(template_name='registration/login.html')),
# This is my attempt for capturing the pdf prefix
# and calling this same file afterwards with the pdfOutput variable set to True
url(r'^pdf/', include('sonata.urls'), kwargs={'pdfOutput':True}),
url(r'^admin/', include(admin.site.urls)),
url(r'^person/', include('person.urls')),
url(r'^registration/', include('registration.urls')),
url(r'^menu/', registration_views.menu, name='menu'),
url(r'^customers/', person_views.customers, name='customers'),
url(r'^employees/', person_views.employees, name='employees'),
url(r'^alumns/', person_views.alumns, name='alumns'),
url(r'^teaching/', person_views.docencia, name='teaching'),
url(r'^i18n/', include('django.conf.urls.i18n')),
)
Is there any way of doing this? I looked at the docs. It seems pretty clear how to pass values, but after proving I can't make the include. (I don't want either to do include() with the [array] of patterns repeating all urls. This would break DRY principle).
Thanks in advance
The problem is that include immediately imports the included url configuration, resulting in a circular import error. You can do something like this, though:
sonata_patterns = [
url(r'^$',TemplateView.as_view(template_name='registration/login.html')),
url(r'^admin/', include(admin.site.urls)),
url(r'^person/', include('person.urls')),
url(r'^registration/', include('registration.urls')),
url(r'^menu/', registration_views.menu, name='menu'),
url(r'^customers/', person_views.customers, name='customers'),
url(r'^employees/', person_views.employees, name='employees'),
url(r'^alumns/', person_views.alumns, name='alumns'),
url(r'^teaching/', person_views.docencia, name='teaching'),
url(r'^i18n/', include('django.conf.urls.i18n')),
]
urlpatterns = [
url(r'^pdf/', include(sonata_patterns), kwargs={'pdfOutput':True})
] + sonata_patterns
Another possibility is to use middleware to capture the pdf prefix and set an attribute on the request. That way, you won't have to worry if all views accept your pdfOutput argument.

django urls.py structure for login, logout, signup ( not app-specific urls ) : in users app or project default app?

Question
I am managing a small django project. and our team has conflicting opinions about this problem :
which is recommended way to put login, logout, signup ( not app-specific routers )?
# Login, Logout
url(r'^login/$', 'users.views.login_view', name='login'),
url(r'^logout/$', 'users.views.logout_view', name='logout'),
url(r'^signup/$', 'users.views.signup', name='signup'),
1. MY_PROJECT > urls.py
Reason : should see overall urls in MY_PROJECT/urls.py and login, logout, signup is not app-specific urls.
2. users > urls.py
Reason : should move login, logout, signup to users app, because view is implemented in users/views.py, and it is preferred way in the view of modularity.
Folder Structure
.
├── MY_PROJECT
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── manage.py
└── users
├── __init__.py
├── models.py
├── urls.py
└── views.py
Additional Information for implemetation
Users app is for extending base User using UserProfile
from django.db import models
from django.contrib.auth.models import User
class UserProfile(models.Model):
user = models.OneToOneField(User, unique=True, primary_key=True)
and so on ...
and also, expending default login, logout, signup view. for example :
def login_view(request):
return default_login_view(
request, template_name="users/login.html"
)
def logout_view(request):
logout(request)
return redirect("home")
If you put all general urls of your project in MY_PROJECT/urls.py after a while number of lines of this file increases a lot. Then when you need to track a specific url, looking through this file could be hard.
So if all urls in MY_PROJECT/urls.py be in following format, you can save a lot of time in searching for a specific url and your code is more cleaner too.
(r'^foo/', include('foo.urls')),
But if your users app is large, maybe if you use a seperate urls.py for login/logout/signup be a better approach. It means in your users app put urls.py and auth_urls.py seperate.

Django REST Framework: How to add prefix in URL for versioning

I am trying to create version for REST application. Here is my URL Examle
www.myapi.com/foo [default version]
www.myapi.com/v1/foo [version one]
This is the project structure
├── __init__.py
├── settings.py
├── urls.py
├── default_app
│ ├── __init__.py
│ ├── serializer.py
│ ├── models.py
│ ├── views.py
│ ├── urls.py
│
└── v1_app
├── __init__.py
├── serializer.py
├── models.py
├── views.py
├── urls.py
default_app urls.py
from django.conf.urls import *
from default_app import views as df_views
from rest_framework import routers
router = routers.DefaultRouter()
router.register(r'foo', df_views.viewname, "foo")
urlpatterns = router.urls
v1_app urls.py
from django.conf.urls import *
from v1_app import views as ver_views
from rest_framework import routers
router = routers.DefaultRouter()
router.register(r'foo', ver_views.viewname, "foo")
urlpatterns = router.urls
main file for urls.py
from django.conf.urls import patterns, include, url
from defualt_app import urls as default_urls
from v1_app import urls as v1_urls
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
urlpatterns += patterns('',
url(r'^', include(default_urls, namespace="default")),
url(r'^v1/', include(v1_urls, namespace="v1"))
)
urlpatterns += staticfiles_urlpatterns()
My issue is, when i using simple url without any prefix then it is working
www.myapi.com/foo
and when i used version prefix v1 or v2 then it throws error [Page not found (404)]
www.myapi.com/v1/foo
I got this idea from this link
https://stackoverflow.com/a/21839842/1558544
If I don't use middleware class then is this possible to get same result?
Thank you
Django REST Framework does not support url namespaces well, but there are solutions to making them work for most cases.
In the case of serializers, you must define all fields that are hyperlinked with a HyperlinkedRelatedField, including the url field that is automatically added, which is a HyperlinkedIdentityField. This includes setting the view_name argument on all of the fields to the correct, automatically generated view name. This should be something like [namespace]:[base_name]-detail.
But this also means you cannot use the DefaultRouter index page that is generated by the DefaultRouter, as it does not handle namespaces at all. In order to get one, you are going to need to either create your own, or override the automatically generated view in the router.

Moving django apps into subfolder and url.py error

I have a question about putting django apps into "apps" subdirectory. I have the app called “faktura” in a project_root. I didn’t like the fact it lies there and I want to store all my apps under “apps” subdirectory.
So, I found out that I could extend python path to “apps” subdir, so after looking in the internet, I added this string to settings.py: sys.path.insert(0, os.path.join(PROJECT_PATH, "apps")). Then I added the app to INSTALLED_APPS like “faktura”. Everything worked smooth until I added url(r'^faktura/', include('faktura.urls')) to urls.py in the root. Since that, Django throws the error message “No module named faktura” full taceback is here: http://dpaste.com/737380/
What can be wrong here, why only urls.py can’t find the app? And does it can’t find this app if I added it to the PATH? I spent a morning trying to figure out what’s wrong and now I need your help.
I don't know why the previous answer got -1 aside from maybe a few redundant lines that can be corrected. Anyway, I found a slightly different method that doesn't involve adding anything to the python path.
This is my final directory structure, I will explain in a moment:
mysite
├── mysite
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── apps
│ ├── __init__.py
│ └── myfirstapp
│ ├── __init__.py
│ ├── admin.py
│ ├── models.py
│ ├── tests.py
│ └── views.py
└── manage.py
No matter if you have just created your project or if you want to move your apps, create the apps subdirectory that should contain your apps. The trick is to add an __init__.py to that directory.
mkdir apps
touch apps/__init__.py
Now you can move your existing apps into the apps subdirectory. If you would like to create a new one instead here are the commands:
python manage.py mysecondapp
mv mysecondapp apps/
Warning: Don't be tempted to call python manage.py ./apps/mysecondapp. For some reason this deletes all other apps in that directory. I just lost a day of work this way.
Next, you will need to fix a few imports. Your settings.py should be prefixed with apps:
INSTALLED_APPS = (
...
'apps.myfirstapp',
'apps.mysecondapp'
)
Lastly, fix your project's urls.py to prefix apps:
urlpatterns = patterns('',
url(r'^myfirstapp', include('apps.myfirstapp.urls')),
...
)
Depending on how you wrote them, you might also have to fix a few imports inside your app. Either just use from models import MyFirstModel or also prefix it using from apps.myfirstapp.models import MyFirstModel.
In short, if you make your apps directory a python package (by adding __init__.py), you can use it as part of the import path. This should work regardless of the deployment method with no extra configuration.
Use BASE_DIR variable from the settings.py. It should be already defined:
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
Better not use the __file__ attribute in manage.py and wsgi.py, as they are located in different directories.
So, just add the following to manage.py and wsgi.py (and to the celery.py if you use Celery):
from django.conf import settings
sys.path.append(os.path.join(settings.BASE_DIR, "apps"))
You will end up with the following project structure:
project
├── project
│ ├── __init__.py
│ ├── celery.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── apps
│ ├── app1
│ └── app2
└── manage.py
To keep your Django applications in a subfolder (such as apps/), first add the following to your settings.py:
import os
PROJECT_ROOT = os.path.dirname(__file__)
Then in manage.py:
Right under #!/usr/bin/env python add:
import sys
from os.path import abspath, dirname, join
from site import addsitedir
Right before if __name__ == "__main__" : add:
sys.path.insert(0, join(settings.PROJECT_ROOT, "apps"))
#Radu Gheorghiu's answer; It is not necessary to edit settings.py, and the insert path line can be condensed to 1 line of code.
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "apps"))
I sourced this answer from http://obroll.com/nested-application-inside-apps-sub-folder-in-django-1-3/