Django Homepage 400 when debug=False - python

So my app works fine in the development server when Debug=True, however, when I switch it to False, my homepage is giving me back a 400 back. I have some endpoints which return json and they work fine regardless of the debug value.
I'm using Django 1.10.2
urls.py
from django.conf.urls import url
from django.contrib import admin
from fim_table import views
urlpatterns = [
url(r'^$', views.create_home),
url(r'^data/', views.data),
...
]
views.py
from django.shortcuts import render
from django.views.decorators.csrf import csrf_protect
from lockdown.decorators import lockdown
from .models import Fim, FimDeleted
from django.http import HttpResponse
from django.db.models.functions import Lower
from django.template.context_processors import csrf
import json
#csrf_protect
def create_home(request):
return render(request, 'table.html', {'csrf': csrf})
# returns all of the data, unfiltered/response is json
#csrf_protect
def data(request):
# show distinct names only
fims = Fim.objects.annotate(name_lower=Lower('crib_name')).order_by('name_lower').distinct('name_lower')
# fims need to be not a queryset but an array of dicts to be json
dictionaries = [ idToString(name.as_dict()) for name in fims ]
mydata = {"aaData": dictionaries}
return HttpResponse(json.dumps(mydata), content_type='application/json')
settings.py
DEBUG = False
ALLOWED_HOSTS = ["*"]
update
I implemented some logging, and got:
The joined path (/DataTables/datatables.min.css) is located outside of the base path component (/Users/me/development/my_project/myapp/staticfiles).
I'm thinking this is a whitenoise issue, even though I set up my settings.py exactly like it is in their docs

Try adding hostnames in the allowed hosts section.
For Ex: ALLOWED_HOSTS = ['localhost', 'localhost_projectname', 'server_hostname']
You can find more details about how to add 404 and 500 pages in your site in the given blog post,
https://micropyramid.com/blog/handling-custom-error-pages-in-django/

Related

Unable to POST data with the Django REST Framework : Not Found

I'm trying to figure out why the Django REST Framework throws a 404 Not Found when I POST data with the code below, because when I load the browsable API with the URL it correctly displays the object list with the HTML form to POST data.
The Django project that serve the API run in a Docker container as well as the client, but in a separate Docker host.
How could I fix the issue ?
Server
Console logs
django-1 | Not Found: /api/strategy/target/
django-1 | [26/Sep/2022 14:27:05] "POST /api/strategy/target/ HTTP/1.1" 404 23
project/project/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path("api/strategy/", include("strategy.urls")),
]
strategy/urls.py
from django.urls import path, include
from rest_framework import routers
from strategy.api.views import TargetViewSet
router = routers.DefaultRouter()
router.register("target", TargetViewSet, basename="targets-list")
urlpatterns = [
path('', include(router.urls)),
]
strategy/views.py
from rest_framework import viewsets
from strategy.api.serializers import TargetSerializer
from rest_framework.decorators import permission_classes
from rest_framework.permissions import IsAdminUser
# Create new model
#permission_classes([IsAdminUser])
class TargetViewSet(viewsets.ModelViewSet):
serializer_class = TargetSerializer
queryset = Target.objects.all()
Client
res = requests.post("http://1.2.3.4:8001/api/strategy/target/",
data=data,
headers={'Authorization': 'Bearer {0}'.format(token)}
)
router.register("target", TargetViewSet, basename="targets-list")
The defination of the router is correct but I think the basename you have there is the problem. Since you have a queryset defined in your views, you can remove the basename completely. You only need to use basename if you define your own get_queryset function.
So try this and let's see if it works out for you.
router.register("target", TargetViewSet")

(Django) Trying to figure out how I can get the right product using query parameters on Postman (url.py and views.py)

I have been building a sandwich shop app and I succeesfully build models.py and inserted all the product data. However, when I try to call specific products using Postman and the Django server, it keeps showing 404. What I typed on postman is like so:
http://10.58.1.157:8000/product/sandwich?product_id=1
Below are my codes for urls.py and views.py
So far, I have tried:
urls.py
from django.urls import path
from .views import ProductView
urlpatterns = [
path('sandwich/int:<product_id>/', ProductView.as_view()),
]
and:
urls.py
path('sandwich/(?P<product_id>[\w.-]+)/', ProductView.as_view())
views.py
import json
import bcrypt
import jwt
from django.views import View
from django.shortcuts import render
from django.http import HttpResponse, JsonResponse
from django.db.models import Q
from .models import Product, Category, SubCategory
class ProductView(View):
def get(self, request):
product_id = request.GET.get('product_id', None)
return JsonResponse({'product_name':Product.objects.get(id=product_id).values()})
To clarify the GET request, I will add the screenshot of Postman below:
It seems like this is due to malformed URL path. That's whats typically indicative of 404-NotFound error.
You need to add question mark that essentially forms the querystring. It is processed and available as a dictionary-like object (a QueryDict) in request.GET in views.py
You can define it like so, with a ? using a REGEX pattern (You may also alter to your needs)
path('sandwich/(?P<product_id>[\w.-]+)/', ProductView.as_view()),
In your views.py you can filter them with
product_id = request.GET.get('product_id', None)
This should now hopefully return a response now that the URL cannot give a 404 error.
See this for an example
I finally solved the issue!
I looked at this page and improvised accordingly...
https://docs.djangoproject.com/en/3.0/topics/http/urls/#nested-arguments
the final version of request is:
http://127.0.0.1:8000/product/?product_id=1
and the urls.py is:
from django.urls import path, re_path
from .views import ProductView
urlpatterns = [
re_path(r'^(?:\?product_id=(?P<product_id>\d+)/)?$', ProductView.as_view()),
]

django returning or posting wrong template html?

I developed a django project named "dms" and an app which name is "add_excel" last month. The app receieves excel files from web page and store the data into mysql database. Today I added another two apps, "add_struc" and "homepage", which should be another function app and the homepage app. But something odd shows up. After I clicked the "upload" button in "add_excel" app, instead of it's original functions, it redirects to "homepage" without doing anything to the database.
The VS Code shows:
[18/Apr/2019 11:08:00] "GET / HTTP/1.1" 200 317 # I opened the
homepage
[18/Apr/2019 11:08:02] "GET /addexcel/index/ HTTP/1.1" 200 1341 # I clicked to the "add_excel" app hyperlink
[18/Apr/2019 11:08:20] "POST /homepage/index/ HTTP/1.1" 200 317 #
I clicked "upload" but it redirected me to homepage again.
If I delete the homepage url in the urls.py for the whole project, and click the upload button again, it says:
Page not found (404) Request Method: POST Request
URL: http://127.0.0.1:8000/homepage/index/ Using the URLconf defined
in dms.urls, Django tried these URL patterns, in this order:
^admin/ ^$ [name='index'] ^addexcel/ ^addstruc/ The current path,
homepage/index/, didn't match any of these.
The urls.py in dms project:
from django.contrib import admin
from django.conf.urls import url, include
from homepage.views import index # default homepage
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^$', index, name='index'), # homepage
url(r'^addexcel/', include('add_excel.urls')),
url(r'^addstruc/', include('add_struc.urls')),
]
urls.py in add_excel app:
from django.conf.urls import url
from django.urls import path
from django.contrib import admin
from add_excel.views import IndexView
urlpatterns = [
url(r'index/', IndexView.as_view(), name ='index'),
]
urls.py in add_struc app:
from django.conf.urls import url
from django.urls import path
from django.contrib import admin
from add_struc.views import IndexView
urlpatterns = [
url(r'index/', IndexView.as_view(), name ='index'),
]
urls.py in homepage app:
from django.conf.urls import url
from django.urls import path
from django.contrib import admin
from homepage.views import index
urlpatterns = [
url(r'index/', index, name='index'),
]
views.py in add_excel app:
# -*- coding:utf-8 -*-
import os
import os.path
import sys
import datetime
from builtins import int
from django.db import models
from django.shortcuts import render
from django.views import View
import pymysql
import xlrd
from xlrd import xldate_as_tuple
# Create your views here.
class IndexView(View):
template_name = 'add_excel/index.html'
context={}
def get(self, request):
return render(request, 'add_excel/index.html', {})
def post(self, request):
# if request.method == 'POST' and 'excel_file' in request.POST:
if request.method == 'POST' and request.FILES["excel_file"]:
# do something
return render(request, 'add_excel/index.html', {"excel_data":excel_data})
You are using the name index in all of your url patterns which is causing a conflict. These should be properly namespaced (homepage-index, excel-index etc.) so when you refer to them throughout your application it is obvious to both developers and the program which URL should be chosen.
My theory is that there is some URL generation in your HTML Form that uses the name index and your Django site chooses the homepage for the URL so your IndexView is not run.

The custom page 404 is not showing but the page 500 is showing

When I load an inexistent url the page 404 does not show instead the page 500 is shown. Below my setups. Could you please guide me to turn Django on to show 404 page? Thanks
Ubuntu Server 16.04 ; Python 3.5.2 ; Django 2.0
cat contatoproj/urls.py
from django.contrib import admin
from django.urls import path
from django.conf.urls import url
from django.conf.urls import include
from django.conf.urls import handler404, handler500
from contatoapp import views
from contatoapp import views as myapp_views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^$', views.index, name='index'),
url(r'^contato', views.contato, name='contato'),
]
handler404 = myapp_views.error_404
handler500 = myapp_views.error_500
cat contatoapp/views.py
from django.shortcuts import render
from django.http import HttpResponse
from django.template import RequestContext
from django.contrib import messages
from django.core.mail import send_mail, BadHeaderError
from django.http import HttpResponse, HttpResponseRedirect
from django.conf import settings
from contatoapp.forms import ContatoForm
def error_404(request):
data = {}
return render(request, 'ops404.html', data)
def error_500(request):
data = {}
return render(request, 'ops500.html', data)
$ ls -la templates/ops*
-rwxr-xr-x 1 admweb admweb 614 Dec 13 15:31 templates/ops404.html
-rwxr-xr-x 1 admweb admweb 614 Dec 13 15:29 templates/ops500.html
cat contatoproj/settings.py
DEBUG = False
ALLOWED_HOSTS = ['*']
If you're getting a 500 error for missing pages then it's because there is an error happening when Django tries to handle that response.
From looking at your code, this is probably because your 404 error handler is wrongly defined - it needs to accept a second exception argument which is missing. Change it to:
def error_404(request, exception):
data = {}
return render(request, 'ops404.html', data)
Also note that you should be returning a HttpResponseNotFound, otherwise the client will not receive a HTTP 404 response.
You're getting an error in the process of handling the 404. This means you're getting a 500 instead.
As you're not doing anything special in your 500 or 404 views, you don't need to explicitly define the handler views for them using handler404/500.
Instead, you should define 404.html and 500.html in your templates directory. Django will use these instead of the default templates, and you don't need to re-implement the 404 and 500 views correctly.

Django reporting 404 error on simple view?

I'm just barely getting started with Python and Django.
I've created my modules, migrated, added my modules to the admin section, etc. Now, I need to create my first view. I've been following this guide (Yes the machine I'm on is running 1.6)
My views.py file in the app (setup) looks like this...
from django.shortcuts import render
from django.http import HttpResponse
def index(request):
return HttpResponse("Setup Index")
My app'a urls.py looks like this...
from django.conf.urls import patterns, url
from setup import views
urlpatterns = patterns('',
url(r'^$', views.index, name='index')
)
And my root urls.py looks like this...
from django.views.generic import TemplateView
from django.views.generic.base import RedirectView
from django.conf.urls import include, patterns, url
from django.contrib import admin as djangoAdmin
from admin.controller import ReportWizard
from admin.forms import reportDetailsForm, reportDataViewsForm
from setup import views
djangoAdmin.autodiscover()
urlpatterns = patterns('',
url(r'^django-admin/', include(djangoAdmin.site.urls)),
#New User Wizard URL
url(r'^setup/', include('setup.urls')),
)
As far as I can tell I have followed the guide to the letter, but I am recieving a 404 error when navigating to myIP/setup.
There are no error messages on the 404 page. What is the issue?
For some reason your settings seem to override the default for either APPEND_SLASH or MIDDLEWARE_CLASSES.
Opening http://example.com/setup should cause a redirect to http://example.com/setup/, but somehow it doesn't for you.
Note that the latter URL is matched by your urls.py while the former is not (as should be the case).
The above should work if 'CommonMiddleWareis enabled andAPPEND_SLASHis set toTrue`.

Categories