Pulling data from db causing 404 page not found error - django

I'm trying to filter my views in such a way that when a specific school is chosen, pk of the school will be placed in a view function called major which would further query the db to display the proper majors corresponding to that school.
I now get a page not found 404 error, and can't figure out why.
url.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
path('<int:Major>/', views.Major, name='Major')
]
models.py
from django.db import models
class Major(models.Model):
name = models.CharField(max_length=30, db_index=True)
class School(models.Model):
name = models.CharField(max_length=50, db_index=True)
school_Major_merge = models.ManyToManyField(Major, through='School_Major')
class School_Major(models.Model):
major = models.ForeignKey(Major, on_delete=models.CASCADE)
school = models.ForeignKey(School, on_delete=models.CASCADE)
class professor(models.Model):
ProfessorIDS = models.IntegerField()
ProfessorName = models.CharField(max_length=100)
ProfessorRating = models.DecimalField(decimal_places=2,max_digits=4)
NumberofRatings = models.CharField(max_length=50)
#delete major from the model
school = models.ForeignKey(School , on_delete=models.CASCADE)
major = models.ForeignKey(Major , on_delete=models.CASCADE)
def __str__(self):
return self.ProfessorName
views.py
from django.http import HttpResponse
from django.shortcuts import render
from .models import professor, School, Major, School_Major
def index(request):
schools = School.objects.all()
return render(request, 'locate/index.html', {'schools': schools})
def Major(request, school_pk):
#Filter to a show the association of 1 schools majors
school_choice = Major_School.objects.filter(school_id = school_pk)
#Filter majors names required
majors = Major.objects.filter(id = school_choice.major_id)
return render(request, 'locate/major.html', {'majors' : majors})
I will post the code for the index file which pulls the schools info below, and when clicking on the school (hyperlink set) its basically suppose to pass the primary key of the school into the Major function which would then do further filtering.
<ul>
{% for list in schools %}
<li>{{list.name}}</li>
<br><br>
{%endfor%}
</ul>
The primary key for the school is pulled properly but for some reason the function doesn't fire up when I click on the hyperlink for the school I receive the 404 page not found error.
Purpose of the Major function,
1) Receive the Primary key of school, which will be passed to the M2M Table.
2) Now that ONLY majors corresponding to that school are displayed, Filter and store ONLY the majors which have the primary keys associated to the school chosen
I think the logic of my function is correct, I just can't understand again why i'm getting the 404 error.
Here is the exact error when I click the first school, which has a PK = 1
The current path, locate/{% url 'Major' 1/, didn't match any of these.
Update:
I went based on the suggestions below, and an example I had laying around that the format I have for the index.html is proper for the dispatcher, as well as the dispatcher is set properly aswell but WHY OH WHY does the {% still pop up I don't get it, I restarted the server thinking maybe it was bugging around but nada.
index.html
{% for list in schools %}
<li>{{list.name}}</li>
<br><br>
{%endfor%}
urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
path('<int:school_pk>/', views.Major, name='Major')
]
The current path Error I'm having is still the same, but what I don't understand is after fixing the template to the proper format (I also used a example project I had as a reference that doesn't have this issue that passes a parameter) i'm not passing just the /locate/school_pk but the curly braces and the %
locate/ [name='index']
locate/ <int:school_pk>/ [name='Major'] <== This one
admin/
register/ [name='register']
profile/ [name='profile']
login/ [name='login']
logout/ [name='logout']
[name='blog-home']
about/ [name='blog-about']
post/<int:pk>/ [name='post-detail']
post/new/ [name='post-create']
post/<int:pk>/update/ [name='post-update']
post/<int:pk>/delete/ [name='post-delete']
user/<str:username> [name='user-posts']
^media/(?P<path>.*)$
The current path, locate/{% url 'Major' 1/, didn't match any of these.
Notice the {% is added in there, even after I fixed my mistake.

I think the template should be:
<li>{{list.name}}</li>
Where the URL is something like this:
path('<int:school_pk>/', views.Major, name='Major')
For reference please check the documentation.

In your for loop it should be
<ul>
{% for list in schools %}
<li>{{list.name}}</li>
<br><br>
{%endfor%}
</ul>
Just remove double curly braces {{ }}

So I noticed that there was a space between this specific url dispatcher in the error message
locate/ [name='index']
locate/ <int:school_pk>/ [name='Major'] <== This one
admin/
register/ [name='register']
profile/ [name='profile']
login/ [name='login']
logout/ [name='logout']
[name='blog-home']
about/ [name='blog-about']
post/<int:pk>/ [name='post-detail']
post/new/ [name='post-create']
post/<int:pk>/update/ [name='post-update']
post/<int:pk>/delete/ [name='post-delete']
user/<str:username> [name='user-posts']
^media/(?P<path>.*)$
The current path, locate/{% url 'Major' 1/, didn't match any of these.
So I added a space to the url.py which seemed to have done the trick
url.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
path(' <int:school_pk>/', views.Major, name='Major')
]
All my other urls in my main project are setup the same way but don't have this problem, but for some reason everything i tried it wouldn't nudge, I had to place a space in order for it to work

Related

How can I print the url to the order id field of my django form?

I am doing a simple form site with Django. This is what my sites url is looks like: mysite.com/register/12345678
I want to print the part after the register (12345678) to the order id field. When someone goes this mysite.com/register/87654321 url then i want to print it.
How can i do that? These are my codes.(Currently using Django 1.11.10)
forms.py
from django import forms
from .models import Customer
from . import views
class CustomerForm(forms.ModelForm):
class Meta:
model = Customer
fields = (
'order_id','full_name','company','email',
'phone_number','note')
widgets = {
'order_id': forms.TextInput(attrs={'class':'orderidcls'}),
'full_name': forms.TextInput(attrs={'class':'fullnamecls'}),
'company': forms.TextInput(attrs={'class':'companycls'}),
'email': forms.TextInput(attrs={'class':'emailcls'}),
'phone_number': forms.TextInput(attrs={'class':'pncls'}),
'note': forms.Textarea(attrs={'class':'notecls'}),
}
views.py
from django.shortcuts import render
from olvapp.models import Customer
from olvapp.forms import CustomerForm
from django.views.generic import CreateView,TemplateView
def guaform(request,pk):
form = CustomerForm()
if request.method == "POST":
form = CustomerForm(request.POST)
if form.is_valid():
form.save(commit=True)
else:
print('ERROR FORM INVALID')
theurl = request.get_full_path()
orderid = theurl[10:]
return render(request,'forms.py',{'form':form,'orderid':orderid})
customer_form.html
{% extends 'base.html' %}
{% block content %}
<h1>REGÄ°STRATÄ°ON</h1>
<form class="registclass" method="POST">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="btn btn-default">REGISTER</button>
</form>
{% endblock %}
urls.py
from django.conf.urls import url
from django.contrib import admin
from olvapp import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^thanks/$',views.ThankView.as_view(),name='thank'),
url(r'^register/(?P<pk>\d+)',views.guaform,name='custform'),
]
You have passed the value to your view as 'pk' so you can use that to set the the initial value:
views.py
form = CustomerForm(initial={'order_id': pk})
SamSparx is right, here's some additional information to help prevent such errors in advance:
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^thanks/$',views.ThankView.as_view(),name='thank'),
url(r'^register/(?P<pk>\d+)',views.guaform,name='custform'),
]
You are using regex to parse your path. Regex is generally speaking not recommended in this case according to the docs because it might introduce more errors and is harder to debug. (Unoptimized) RegEx also tends to be slower.
For simple use cases such as your path here, consider choosing the default pathing syntax as below:
urlpatterns = [
url('admin/', admin.site.urls),
url('thanks/',views.ThankView.as_view(),name='thank'),
url('register/<int:pk>',views.guaform,name='custform'),
]
You could of course also use string instead of int depending on your usage of pk.
Your paths do not all end with a slash consistently. This might impact your SEO and confuse users. See this and this.
Also your form is not imported .as_view() for some reason which could cause some problems.

Beginner Django / Python / Postgres dev struggling with no model data output to html file

I have been working through some basic online Youtube tutorials for Django, which have been great, but I've been struggling the last few days with my Test-table app, being unable to display table data on my example Postgresql table placed on my index.html file. When I created the Postgres model (local hosted), it appears correctly with data in the admin page, and my index page loads successfully from my url and view file configurations, but is missing the table data specifically and I'm hoping for some guidance on what I am doing incorrectly. I understand there are more dynamic configurations for the URL and views, but I was attempting to get a basic one working first...
models.py file:
from django.db import models
class products(models.Model):
Phone = models.TextField(primary_key=True)
Version = models.TextField(max_length=100)
Price = models.FloatField()
Sales = models.IntegerField()
class Meta:
db_table = "productlist"
Url file:
from django.contrib import admin
from django.urls import path
from . import views
app_name = 'Test_table'
urlpatterns = [
path('admin/', admin.site.urls),
path('', views.sales),
]
views.py
from django.shortcuts import render
from Test_table.models import products
# from django.http import HttpResponse
def sales(request):
ph_data = products.objects.all(),
return render(request, 'Test_table/index.html', {'ph_data': ph_data})
html file:
<table border='3'>
<tr>
<th>Phone</th>
<th>Version</th>
<th>Price</th>
<th>Sales</th>
</tr>
{% for i in ph_data %}
<tr>
<td><h3>{{i.Phone}}</h3></td>
<td><h3>{{i.Version}}</h3></td>
<td><h3>{{i.Price}}</h3></td>
<td><h3>{{i.Sales}}</h3></td>
</tr>
{% endfor %}
</table>
Just remove , from ph_data = products.objects.all(), , rest is fine
Correct code :
from django.shortcuts import render
from Test_table.models import products
# from django.http import HttpResponse
def sales(request):
ph_data = products.objects.all()
return render(request, 'Test_table/index.html', {'ph_data': ph_data})
And make sure to add data from admin to products table to view it.

django.urls.exceptions.NoReverseMatch: Reverse for 'Professors' with arguments '(1, 5)' not found

I'm trying to filter my professor table to display the professors that correspond to a specific school and specific major, the parameters are showing up in the error message, I just don't understand why there is a error message at all.
Views.py
from django.http import HttpResponse
from django.shortcuts import render
from .models import professor, School, Major, School_Major
def index(request):
schools = School.objects.all()
return render(request, 'locate/index.html', {'schools': schools})
# def Major(request, Major):
# major_choice = professor.objects.filter(Major =Major)
# return render(request, 'locate/major.html', {'major_choice': major_choice})
def Majors(request, school_pk):
schools_majors_ids = []
major_after_filter = []
#Filter to a show the association of 1 schools majors
school_choice = School_Major.objects.filter(school_id = school_pk)
#Append each of the major id's to school_majors_ids list
for store in school_choice:
schools_majors_ids.append(store.major_id)
#Filter majors names required
for store in schools_majors_ids:
name = Major.objects.get(id = store)
major_after_filter.append(name)
return render(request, 'locate/major.html', {'major_after_filter' : major_after_filter,
'school_pk' : school_pk})
def Professors(request, school_pk, major_pk):
professors = professors.objects.filter(school_id = school_pk).filter(major_id = major_pk)
return render(request, 'locate/professors', {'professors' : professors})
url.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
path(' <int:school_pk>/', views.Majors, name='Major'),
path(' <int:school_pk/<int:major_pk>/', views.Professors, name="Professors")
]
majors.html
<h3 id="test">{{school_pk}}</h3>
<ul>
{% for major in major_after_filter %}
<li>{{major.name}}</li>
{%endfor%}
</ul>
I needed a way to place the value of the schools primary key, as well as the majors primary key as parameters for the Professor view function to be able to filter down the professor table in order to display the correct majors.
When I leave school_pk as seen below
I get the following error
django.urls.exceptions.NoReverseMatch: Reverse for 'Professors' with arguments '(1, 5)' not found. 1 pattern(s) tried: ['locate/\\ <int:school_pk/(?P<major_pk>[0-9]+)/$']
When I remove the school_pk like below
<li>{{major.name}}</li>
I get this error
TypeError: Professors() missing 1 required positional argument: 'school_pk'
Which makes sense because the professor function requires a school_pk parameter (Note that the variable used in the html and parameter are named the same sorry if that seems confusing).
You're missing a close bracket in your URL pattern.
path('<int:school_pk>/<int:major_pk>/',
^

ListView in Django Assistance

OK, so I have just done a rather extensive Django tutorial online and wanted to dive into my first project to see how I would go.
I started off alright and then hit a pretty big road block that I am trying to overcome with no luck, so if you guys could help I will be forever in your debt!
So the project itself is simply making a website for a few of my mates where we can login and view some stats on bets we have with each other.
What I have done so far:
I created two models in models.py with the following code:
from django.db import models
# Create your models here.
class Team(models.Model):
team_name = models.CharField(max_length=500, unique=True)
wins = models.PositiveIntegerField()
losses = models.PositiveIntegerField()
class Predictions(models.Model):
combined_teams = models.CharField(max_length=800)
player_name = models.CharField(max_length=200, primary_key=True)
predicted_wins = models.PositiveIntegerField()
def __str__ (self):
return self.player_name
I created a login screen, this is the first screen the user will come to (not relevant for the question)
I created a static folder with some css styling for a couple of the pages and made some minor changes to the settings files.
I then went on to setup my views.py file and a couple of urls.py files too, as follows:
###VIEWS.PY####
from django.shortcuts import render
from django.views.generic import TemplateView, ListView
from django.contrib.auth.mixins import LoginRequiredMixin
from .models import Predictions, Team
class WelcomeView(LoginRequiredMixin,TemplateView):
template_name = 'merchbet/welcome.html'
class HomeView(LoginRequiredMixin, TemplateView):
template_name = 'merchbet/home.html'
class PredictionListView(LoginRequiredMixin, ListView):
model = Predictions
def get_queryset(self):
return Predictions.objects.order_by('-player_name')
class GalleryView(LoginRequiredMixin,TemplateView):
template_name = 'merchbet/gallery.html'
URLS.PY
from django.contrib import admin
from django.urls import path,include
from django.contrib.auth.urls import views
urlpatterns = [
path('', views.LoginView.as_view(), name='login'),
path('account/profile/', include('merchbet.urls')),
path('admin/', admin.site.urls),
]
URLS.PY### IN MY APP FOLDER
from django.urls import path
from . import views
app_name = 'merchbet'
urlpatterns = [
path('', views.WelcomeView.as_view(), name='welcome'),
path('home/', views.HomeView.as_view(), name='home'),
path('predictions/', views.PredictionListView.as_view(), name='prediction_list'),
path('gallery/', views.GalleryView.as_view(), name='gallery')
I then executed the following script, so that I could load up my friends "predictions" for our NBA bets this season with the following program:
import os
os.environ.setdefault('DJANGO_SETTINGS_MODULE','mysite.settings')
import django
django.setup()
from merchbet.models import Predictions, Team
predictions = ['Burger', 'Houston Rockets and Oklahoma City Thunder', 101,
'Buzz','Houston Rockets and Boston Celtics', 115, 'Kimon', 'Sacramento Kings and Atlanta Hawks', 44,
'Muller','Utah Jazz and Boston Celtics', 118, 'Barlow', 'Los Angeles Lakers and Milwaukee Bucks', 102,
'Larter','Golden State Warriors and Atlanta Hawks', 83, 'Hume', 'Los Andeles Lakers and Philadelphia 76ers',
104]
def add_predictions():
for index, entry in enumerate(predictions):
if index < len(predictions)-2:
if (type(predictions[index+2]) == type(1)):
player_name = predictions[index]
combined_teams = predictions[index+1]
predicted_wins = predictions[index+2]
preds = Predictions.objects.get_or_create(player_name=player_name,combined_teams=combined_teams,predicted_wins=predicted_wins)[0]
if __name__ == '__main__':
print("Populating the databases...Please Wait")
add_predictions()
print('Populating Complete')
The above worked fine and I can see in my Django Admin view of the site that there are 7 objects of the Predictions class all named after the "player_name" variable as it is the primary key:
So after all of this I am trying to simply use a for loop in an html document, that will help to print out the "player_name" and then I can show the "combined_teams" and "predicted_wins" but I just can not get it to work.
{% for prediction in prediction_list %}
<h1>{{ prediction.player_name }}</h1>
{% endfor %}
I have put a heap of effort into this post, so I am hoping some genius out there can lend a hand!
edit: I know the colour of the text is white, it is against a black background, so that isn't an issue :-)
Thanks!
You need to use object_list instead of prediction_list for merchbet/prediction_list.html, like this:
{% for prediction in object_list %}
<h1>{{ prediction.player_name }}</h1>
{% endfor %}
For more details, please check the documentation.

NoReverse Match at "" Reverse for "" with arguments '()' and keyword arguments '{}'

I'm trying to display a list of links to a list view in Django but I keep getting a "NoReverse Match" error.
Template
{% for posts in all_posts %}
{{posts.title}}
{% endfor %}
Views
from blog.models import Posts
from main_site.views import LayoutView
class BlogView(LayoutView, generic.ListView):
template_name = 'blog/blog.html'
model = Posts
context_object_name = 'all_posts'
Blog / urls
urlpatterns = patterns('',
url(r'^(?P<slug>\w+)/$', views.SingleView.as_view(), name='blog_single'),
url(r'^$', views.BlogView.as_view(), name='blog_home'),
)
Project /urls
urlpatterns = patterns('',
url(r'^blog/', include('blog.urls', namespace='blog')),
)
slug is property in my model set to models.SlugField() and if I output as just {{posts.slug}} it shows up so I know it's not empty. I have a similar link set up in a different app in the project that's working fine (exact same set up -- url 'namespace:name') so I'm not sure what's causing this to break.
The full error is:
NoReverseMatch at /blog/
Reverse for 'blog_single' with arguments '(u'test-slug',)' and keyword arguments '{}' not found. 1 pattern(s) tried: [u'blog/(?P<slug>\\w+)/$']
this is because you have bad url pattern.
url(r'^(?P<slug>\w+)/$', views.SingleView.as_view(), name='blog_single'),
is expecting \w+ (that is any letter character, number character or underscore). But you are supplying it with a text containing a dash ("-").
So you need change your slug or url pattern to be like:
url(r'^(?P<slug>[\w-]+)/$', views.SingleView.as_view(), name='blog_single'),