Stuck at django models get_absolute_url. NoReverseMatch - django-models

Its not redirecting and giving the error of NoReverseMatch. exception is: book_detail cannot be found... though i have the correct name and same name in urls.py and template. Even book_detail anchored to the book_list working completely fine. where am i doing the mistake kindly help me.
Details:
[Error]
NoReverseMatch at /catalog/book_create/
Reverse for 'book_detail' not found. 'book_detail' is not a valid view function or pattern name.
Request Method: POST
Request URL: http://127.0.0.1:8000/catalog/book_create/
Django Version: 4.1.3
Exception Type: NoReverseMatch
Exception Value:
Reverse for 'book_detail' not found. 'book_detail' is not a valid view function or pattern name.
Exception Location: C:\Users\Umar\AppData\Local\Programs\Python\Python311\Lib\site-packages\django\urls\resolvers.py, line 828, in _reverse_with_prefix
Raised during: catalog.views.BookCreateView
Python Executable: C:\Users\Umar\AppData\Local\Programs\Python\Python311\python.exe
Python Version: 3.11.0
Python Path:
['C:\Users\Umar\Djano_learning\Django\my_site',
'C:\Users\Umar\AppData\Local\Programs\Python\Python311\python311.zip',
'C:\Users\Umar\AppData\Local\Programs\Python\Python311\Lib',
'C:\Users\Umar\AppData\Local\Programs\Python\Python311\DLLs',
'C:\Users\Umar\AppData\Local\Programs\Python\Python311',
'C:\Users\Umar\AppData\Local\Programs\Python\Python311\Lib\site-packages']
Server time: Mon, 02 Jan 2023 17:02:23 +0000
Models:
class Book(models.Model):
title = models.CharField(max_length=100)
'''Linking Author class model to Book model'''
author = models.ForeignKey('Author',on_delete=models.SET_NULL,null=True)
summary = models.TextField(max_length=600)
isbn = models.CharField(max_length=13, unique=True)
genre = models.ManyToManyField(Genre)
language =
models.ForeignKey('Language',on_delete=models.RESTRICT,null=True)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('book_detail', kwargs={'pk' : self.pk})
[Book_detail.html]
<html lang="en">
<head>
</head>
<body>
<h2>Details of Books</h2>
<h2>{{book}}</h2>
<h2>{{author}}</h2>
</body>
</html>
[Urls.py]
from django.urls import path,reverse_lazy,reverse
from .views import (HomeView,BookListView,
BookCreateView,BookDetailView,AuthorCreateView,AuthorListView,
AuthorDetailView)
from . import views
app_name='catalog'
# path is below
urlpatterns = [
path('',HomeView.as_view(),name='home'),
path('book_list/',BookListView.as_view(),name='book_list'),
path('book_create/',BookCreateView.as_view(),name='book_create'),
**path('book_detail/<int:pk>/',BookDetailView.as_view(),name='book_detail'),**
path('author_create/',AuthorCreateView.as_view(),name='author_create'),
path('author_list/',AuthorListView.as_view(),name='author_list'), path('author_detail/<int:pk>/',AuthorDetailView.as_view(),name='people_detail')
,path('view/',views.auth_check,name='view')
]
A simple Redirect should have to work.

Related

No module named django.urls

I'm trying to create a new model, i named it products, and i found this error message which you see below
Note that my django version is 1.8.7
##urls.py:
from django.contrib import admin
from mySecondGdgBlogs import views
from django.urls import include, path
from myGdgBlogs import views
urlpatterns = [
path('admin/', admin.site.urls),
path('writeafterme/',include('mySecondGdgBlogs.urlss')),
path('htm/', views.htamal),
path('dp/',views.dpmain)
]
##views.py:
from django.http import HttpResponse
from django.shortcuts import render
# Create your views here.
def dbmain(request):
data = ''
return HttpResponse(data)
##models.py
from django.db import models
# Create your models here.
class Products(models.Model):
name = models.CharField (max_length=20)
price = models.IntegerField()
type=models.CharField(max_length=20,choices=(
('S', 'Small'),
('M', 'Medium'),
('L', 'Large'),
))
class Meta:
db_table = 'Products'
I expected to show me a white page but the actual result in the browser is :
No module named 'django.urls'
Request Method: GET
Request URL: http://127.0.0.1:8000/
Django Version: 1.8.7
Exception Type: ModuleNotFoundError
Exception Value:
No module named 'django.urls'
Exception Location: /home/mohammed/PycharmProject/GdgProject/myGdgProject/myGdgProject/urls.py in <module>, line 7
Python Executable: /usr/bin/python3
Python Version: 3.6.8
Python Path:
[
'/home/mohammed/PycharmProject/GdgProject/myGdgProject',
'/usr/local/lib/python3.6/dist-packages/pip-19.1.1-py3.6.egg',
'/usr/lib/python36.zip',
'/usr/lib/python3.6',
'/usr/lib/python3.6/lib-dynload',
'/home/mohammed/.local/lib/python3.6/site-packages',
'/usr/local/lib/python3.6/dist-packages',
'/usr/lib/python3/dist-packages'
]

Displaying Python database on Flask web server

I'm working on a project that requires that I create a create a database, import data into it, and display it on a FLASK local server. I've created the database, but I'm confused as to what I need to do in order to display its tables on the server. I have it set up to display information via HTML through render_template and believe I've established a connection via config.py, but I'm not sure where to go from here. I've read the following guides, but I don't quite understand them. If anybody could assist, I would appreciate it.
http://flask.pocoo.org/docs/0.12/patterns/sqlalchemy/
http://flask-sqlalchemy.pocoo.org/2.3/config/
Below are the relevant files in the project root.
/project
config.py
database_insert.py
server.py
/app
/templates
index.html
__init__.py
models.py
routes.py
config.py
import os
basedir = os.path.abspath(os.path.dirname(__file__))
class Config(object):
SECRET_KEY = 'you-will-never-guess'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////project/app.db'
SQLALCHEMY_TRACK_MODIFICATIONS = False
init.py
from flask import Flask, request, render_template
from config import Config
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
app = Flask(__name__)
app.config.from_object(Config)
db = SQLAlchemy(app)
migrate = Migrate(app, db)
from app import routes, models
models.py
from app import db
class Lot(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(64), index=True)
spots = db.relationship('Spot', backref='author', lazy='dynamic')
def __repr__(self):
return '<Lot {}>'.format(self.username)
class Spot(db.Model):
id = db.Column(db.Integer, primary_key=True)
availability = db.Column(db.String(140))
spot_num = db.Column(db.String(140))
lot_id = db.Column(db.Integer, db.ForeignKey('lot.id'))
def __repr__(self):
return '<Spot {}>'.format(self.body)
routes.py
from app import app
from flask import Flask, request, render_template
#app.route('/')
#app.route('/index')
def index():
lot_details = {
'id': 'TEST_ID', #placeholder for testing purposes
'title': 'TEST_TITLE' #placeholder for testing purposes
}
return render_template('index.html', lot=lot_details)
index.html
<!DOCTYPE html>
<html>
<head>
<title>test</title>
</head>
<body>
<p>Hello, World!</p>
<p>{{lot.id}}</p>
<p>{{lot.title}}</p>
</body>
At first, define helper method in your Spot model class.
class Spot(db.Model):
id = db.Column(db.Integer, primary_key=True)
availability = db.Column(db.String(140))
spot_num = db.Column(db.String(140))
lot_id = db.Column(db.Integer, db.ForeignKey('lot.id'))
def __repr__(self):
return '<Spot {}>'.format(self.body)
def dump(self):
return dict(id=self.id, title=self.title)
Then, in your flask route, you may query:
#app.route('/')
#app.route('/index')
def index():
lot_details = Lot.query.first().dump() # query first item
return render_template('index.html', lot=lot_details)

GAE upload image then dynamically serve the image

I'm trying to make a simple app on GAE that allows a user to enter a url to an image and a name. The app then uploads this image to the Datastore along with its name.
After the upload the page self redirects and then should send the image back to the client and display it on their machine.
After running all I get is a Server error. Since I am new to GAE please could someone tell me if my code is at least correct.
I can't see what is wrong with my code. (I have checked for correct indentation and whitespace). Below is the code:
The python:
import jinja2 # html template libary
import os
jinja_environment = jinja2.Environment(
loader=jinja2.FileSystemLoader(os.path.dirname(__file__)))
import urllib
import urllib2
import webapp2
from google.appengine.ext import db
from google.appengine.api import urlfetch
class Default_tiles(db.Model):
name = db.StringProperty()
image = db.BlobProperty(default=None)
class MainPage(webapp2.RequestHandler):
def get(self):
template = jinja_environment.get_template('index.html')
self.response.out.write(template.render())
class Upload(webapp2.RequestHandler):
def post(self):
# get information from form post upload
image_url = self.request.get('image_url')
image_name = self.request.get('image_name')
# create database entry for uploaded image
default_tile = Default_tiles()
default_tile.name = image_name
default_tile.image = db.Blob(urlfetch.Fetch(image_url).content)
default_tile.put()
self.redirect('/?' + urllib.urlencode({'image_name': image_name}))
class Get_default_tile(webapp.RequestHandler):
def get(self):
name = self.request.get('image_name')
default_tile = get_default_tile(name)
self.response.headers['Content-Type'] = "image/png"
self.response.out.write(default_tile.image)
def get_default_tile(name):
result = db.GqlQuery("SELECT * FROM Default_tiles WHERE name = :1 LIMIT 1", name).fetch(1)
if (len(result) > 0):
return result[0]
else:
return None
app = webapp2.WSGIApplication([('/', MainPage),
('/upload', Upload),
('/default_tile_img', Get_default_tile)],
debug=True)
The HTML:
<html>
<head>
<link type="text/css" rel="stylesheet" href="/stylesheets/main.css" />
</head>
<body>
<form action="/upload" method="post">
<div>
<p>Name: </p>
<input name="image_name">
</div>
<div>
<p>URL: </p>
<input name="image_url">
</div>
<div><input type="submit" value="Upload Image"></div>
</form>
<img src="default_tile_img?{{ image_name }}">
</body>
</html>
Any help at all will be so much appreciated. Thanks you!
UPDATE
Thanks to Greg, I know know how to view error logs. As Greg said I was missing a comma, I have updated the code above.
The app now runs, but when I upload an image, no image shows on return. I get the following message in the log:
File "/Users/jamiefearon/Desktop/Development/My Programs/GAE Fully functional website with css, javascript and images/mywebsite.py", line 53, in get
default_tile = self.get_default_tile(name)
TypeError: get_default_tile() takes exactly 1 argument (2 given)
I only passed one argument to get_default_tile() why does it complain that I passed two?
You're missing a comma after ('/upload', Upload) in the WSGIApplication setup.
use this python code
import jinja2 # html template libary
import os
jinja_environment = jinja2.Environment(
loader=jinja2.FileSystemLoader(os.path.dirname(__file__)))
import urllib
import urllib2
import webapp2
from google.appengine.ext import db
from google.appengine.api import urlfetch
class Default_tiles(db.Model):
name = db.StringProperty()
image = db.BlobProperty(default=None)
class MainPage(webapp2.RequestHandler):
def get(self):
template = jinja_environment.get_template('index.html')
self.response.out.write(template.render())
class Upload(webapp2.RequestHandler):
def post(self):
# get information from form post upload
image_url = self.request.get('image_url')
image_name = self.request.get('image_name')
# create database entry for uploaded image
default_tile = Default_tiles()
default_tile.name = image_name
default_tile.image = db.Blob(urlfetch.Fetch(image_url).content)
default_tile.put()
self.redirect('/?' + urllib.urlencode({'image_name': image_name}))
class Get_default_tile(webapp2.RequestHandler):
def get_default_tile(self, name):
result = db.GqlQuery("SELECT * FROM Default_tiles WHERE name = :1 LIMIT 1", name).fetch(1)
if (len(result) > 0):
return result[0]
else:
return None
def get(self):
name = self.request.get('image_name')
default_tile = self.get_default_tile(name)
self.response.headers['Content-Type'] = "image/png"
self.response.out.write(default_tile)
app = webapp2.WSGIApplication([('/', MainPage),
('/upload', Upload),
('/default_tile_img', Get_default_tile)],
debug=True)

Integrating Chat with (webapp2 + python 2.7 + Jinja2)

I'm trying to add chat to my site and am integrating some code with my existing code. The chat app works fine on its own when it's all set up in the original main.app file. But when I try to move that same code to a handlers.py file and then setup up routes in routes.py I get errors saying template variables are undefined. Are the two different codes conflicting in the way they render templates? They seem to be using webapp2 differently, i.e. my code renders templates like this:
self.render_template('secure_zone.html', **params)
And the chat app like this:
self.response.out.write(render("main.html",
username=username,
usernameerror=usernameerror,
channel=channelname,
channelerror=channelerror))
Are both acceptable?
Here's my handlers.py file:
Routes are setup in routes.py and added in main.py
"""
import httpagentparser
from boilerplate import models
from boilerplate.lib.basehandler import BaseHandler
from boilerplate.lib.basehandler import user_required
class SecureRequestHandler(BaseHandler):
"""
Only accessible to users that are logged in
"""
#user_required
def get(self, **kwargs):
user_session = self.user
user_session_object = self.auth.store.get_session(self.request)
user_info = models.User.get_by_id(long( self.user_id ))
user_info_object = self.auth.store.user_model.get_by_auth_token(
user_session['user_id'], user_session['token'])
try:
params = {
"user_session" : user_session,
"user_session_object" : user_session_object,
"user_info" : user_info,
"user_info_object" : user_info_object,
"userinfo_logout-url" : self.auth_config['logout_url'],
}
return self.render_template('secure_zone.html', **params)
except (AttributeError, KeyError), e:
return "Secure zone error:" + " %s." % e
Here's the main.py file for the chat app:
import os
import hashlib
import urllib
import logging
import re
import json
import webapp2
import jinja2
from google.appengine.api import channel as channel_api # 'channel' is kind of ambiguous in context
from google.appengine.ext import db
from google.appengine.api import memcache
# This section will eventually get moved to a Handler class
template_dir = os.path.join(
os.path.dirname(__file__), 'templates')
jinja_env = jinja2.Environment(
loader = jinja2.FileSystemLoader(template_dir),
autoescape = True)
def render_str(template, **params):
'''Returns a string of the rendered template'''
t = jinja_env.get_template(template)
return t.render(params)
def render(template, **kw):
'''Render using the template and parameters'''
return(render_str(template, **kw))
# End Handler
class Main(webapp2.RequestHandler):
def get(self):
'''Show connection page'''
return self.render_template("main.html", channel="#udacity")
def post(self):
'''Displays chat UI'''
username = self.request.get('username')
channelname = self.request.get('channel')
usernameerror = ""
if not username:
usernameerror="Please enter a username"
elif not re.compile(r'^[a-zA-Z0-9_-]{3,20}$').match(username):
usernameerror = "Username must consist of 3-20 alphanumeric characters."
elif get_user(username):
usernameerror="Username already in use"
channelerror = ""
if channelname and not re.compile(r'^#[\w]{3,20}$').match(channelname):
channelerror="Channel must consist of 3-20 alpha_numeric characters and start with a #"
if len(usernameerror+channelerror) > 0:
self.response.out.write(render("main.html",
username=username,
usernameerror=usernameerror,
channel=channelname,
channelerror=channelerror))
app = webapp2.WSGIApplication([
('/', Main),
('/communication', Communication),
('/_ah/channel/connected/?', Connect),
('/_ah/channel/disconnected/?', Disconnect)
], debug=True)
The specific error you posted in the comments "Error: 'Main' object has no attribute 'render_template'" is because in your Main handler, you try to return self.render_template. You should be just calling the function like this:
render_template("main.html", channel="#udacity")
Please note that I did not check the rest of your code, so if you run into any other issues, please post the specific errors you get.
It is because your webapp2.RequestHandler do not have the corresponding function "render_template"
you can use a BaseHandler with render_template function added to achieve the template rendering
from google.appengine.ext.webapp import template
class BaseHandler(webapp2.RequestHandler):
def render_template(self, filename, **template_args):
path = os.path.join(os.path.dirname(__file__), 'templates', filename)
self.response.write(template.render(path, template_args))
class Main(BaseHandler):
def get(self):
'''Show connection page'''
return self.render_template("main.html", channel="#udacity")
ref: http://blog.notdot.net/2011/11/Migrating-to-Python-2-7-part-2-Webapp-and-templates
I just started using webapp2 + python 2.7 + Jinja2 few days, and that is the same problem I encountered.
Hope this solution can help you ;)

Cannot print data from database using the new version

I am using the latest version of web.py.
I am trying to print data from the database to a webpage.
The code i use is the following
import web
from google.appengine.ext import db
from models import *
urls = (
'/', 'index',
)
render = web.template.render('templates', base='base')
class index:
def GET(self):
votes = db.GqlQuery("SELECT * FROM votes")
return render.index(votes)
app = web.application(urls, globals())
main = app.cgirun()
the template is the following
$def with(votes)
$for vote in votes:
<li>$vote.status</li>
and i am getting this when i run it
[<models.votes object at 0x0000000004525F28>]
Is this a bug with the new version cause in previous version it works.
I forgot to say that i am compiling my templates as stated here.
It works on my machine, running the latest web.py 0.36 with this code:
main.py
import web
from google.appengine.ext import db
class Votes(db.Model):
status = db.StringProperty()
urls = (
'/', 'Index',
)
render = web.template.render('templates', base='base')
class Index:
def GET(self):
vote = Votes()
vote.status ="foo"
vote.put()
votes = db.GqlQuery("SELECT * FROM Votes")
return render.index(votes)
app = web.application(urls, globals())
main = app.cgirun()
templates/index.html
$def with(votes)
$for vote in votes:
<li>$vote.status</li>
templates/base.html
$def with (content)
<html>
<head>
</head>
<body>
$:content
</body>
</html>
this is the result:
foo
I don't use web.py; but maybe it doesn't support generators/iterables in the templates as expected. Try fetching the results first by changing your line to:
votes = db.GqlQuery("SELECT * FROM votes").fetch(100)

Resources