redirect() and NoReverseMatch - python

I am trying to write correct redirection to other view, but now I have no idea
This is my last try:
txt2png/urls.py
urlpatterns = patterns('txt2png.views',
# ...
url(r'^list/(?P<what>\w)/', 'list', name='list-notes'),
url(r'^search/', 'search', name='search-notes'),
)
txt2png/views.py
def list(request, what):
# ...
def search(request):
#...
return redirect(list, 'search')

have you tried the .../list/anything/ ?
It is 404, because of your url config. The (?P<what>\w) means only ONE character, so .../list/a/ will work.
Replace that row in your url config:
url(r'^list/(?P<what>\w+)/', list, name='list-notes'),
(a + sign added to the regex)

Related

Flask - Get list of routes without "#login_required" routes

I found this useful function on pythonprogramming.net to create a sitemap.xml based on all routes defined:
#app.route('/sitemap.xml', methods=['GET'])
def sitemap():
try:
"""Generate sitemap.xml. Makes a list of urls and date modified."""
pages=[]
ten_days_ago=(datetime.now() - timedelta(days=7)).date().isoformat()
# static pages
for rule in app.url_map.iter_rules():
if "GET" in rule.methods and len(rule.arguments)==0:
pages.append(
["http://pythonprogramming.net"+str(rule.rule),ten_days_ago]
)
sitemap_xml = render_template('sitemap_template.xml', pages=pages)
response= make_response(sitemap_xml)
response.headers["Content-Type"] = "application/xml"
return response
except Exception as e:
return(str(e))
So I see app.url_map.iter_rules() iterates through all routes. However, I would like to exclude all routes that have #login_required applied to them.
for example i want:
#bp.route("/")
#bp.route("/index")
def index():
return render_template('index.html')
But I don't want:
#bp.route('/profile')
#login_required
def profile():
return render_template('profile.html')
How can I achieve this? And are there any other useful tips for "accessing properties" of defined routes?
Thanks a lot!
Since I don't have that many "static" pages, for now I solved it by adding a list include_pages and checking the rule.rule against it with and rule.rule in include_pages, like so:
#bp.route('/sitemap.xml', methods=['GET'])
def sitemap():
try:
"""Generate sitemap.xml. Makes a list of urls and date modified."""
include_pages = [
'/'
,'/index'
,'/faq'
,'/privacypolicy'
,'/termsandconditions'
]
pages=[]
ten_days_ago=(datetime.now() - timedelta(days=7)).date().isoformat()
# static pages
for rule in current_app.url_map.iter_rules():
#current_app.logger.debug(rule.rule)
if "GET" in rule.methods and len(rule.arguments)==0 and rule.rule in include_pages:
pages.append(
["http://pythonprogramming.net"+str(rule.rule),ten_days_ago]
)
sitemap_xml = render_template('sitemap_template.xml', pages=pages)
response= make_response(sitemap_xml)
response.headers["Content-Type"] = "application/xml"
return response
except Exception as e:
return(str(e))
Still would be interested to know, if it is somehow possible to get routes excluding #login_required.

Еhere was an error while adding url to test

When I transfer to the test url, an error pops up:
Reverse for 'movie' not found. 'movie' is not a valid view function or pattern name.
Here is my self test:
class BooksApiTestCase(APITestCase):
def setUp(self):
self.movie_1 = Movie.objects.create(title="terminator", year="1990", rating="5",url="retminator")
self.movie_2 = Movie.objects.create(title="robocop", year="1991", rating="4",url="robocop")
self.movie_3 = Movie.objects.create(title="rembo", year="1992", rating="3",url='rembo')
def test_get(self):
url = reverse('movie')
print(url)
response = self.client.get(url)
serializer_data = MovieListSerializer([self.movie_1, self.movie_2, self.movie_3], many=True).data
self.assertEqual(status.HTTP_200_OK, response.status_code)
self.assertEqual(serializer_data, response.data)
Here is my self url:
urlpatterns = format_suffix_patterns([
path("movie/", views.MovieViewSet.as_view({'get': 'list'})),
Hi #Andrew and Welcome to StackOverflow.
To use reverse() you have to properly set the view's name in the urlpatterns
urlpatterns = format_suffix_patterns([
path("movie/", views.MovieViewSet.as_view({'get': 'list'}, name='movie')
]),
Refer to the official documentation

Django Error ---index() missing 1 required positional argument: 'pk'

I have this error when try to open a path. It requires a pk in my def and i inserted it, but still the issue is there. If someone could help, i would owe you a lot!
This is the error i have in browser:
TypeError at /batches/
index() missing 1 required positional argument: 'pk'
Request Method: GET
Request URL: http://127.0.0.1:8000/batches/
Django Version: 1.11.1
Exception Type: TypeError
Exception Value:
index() missing 1 required positional argument: 'pk'
Exception Location: /Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/core/handlers/base.py in _get_response, line 185
Python Executable: /Library/Frameworks/Python.framework/Versions/3.6/bin/python3.6
Python Version: 3.6.1
Python Path:
['/Users/cohen/Documents/project/sanctions',
'/Users/cohen/Documents/project/sanctions',
'/Library/Frameworks/Python.framework/Versions/3.6/lib/python36.zip',
'/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6',
'/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/lib-dynload',
'/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages',
'/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/PyObjC']
Server time: Mon, 24 Jul 2017 10:47:02 +0000
My urls in batches
from django.conf.urls import url
from . import views
urlpatterns = [
# /batches/
url(r'^$', views.index, name='index'),
# /batches/2
url(r'^(?P<batches_id>[0-9]+)/$',views.detail, name="detail"),
# businessname/1
url(r'^(?P<businessname_id>[0-9]+)/$',views.index_businessname, name="detail_businessname"),
# individuals/1
url(r'^(?P<individuals_id>[0-9]+)/$', views.index_individuals, name="detail_individuals"),
]
And the views:
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from .models import BusinessName
from .models import Individuals
from .models import Batches
from django.shortcuts import render
from django.http import HttpResponse
# Create your views here.
def index(request, pk):
all_Batches = Batches.objects.all()
html = ''
for batch in all_Batches:
url = '/batches/' + str(batch.id) + '/'
html += '' + str(batch.BatchNumber)+ '<br>'
return HttpResponse(html)
def detail(request, batch_id):
return HttpResponse("<h2>Details for Batches ID:" + str(batch_id) + "</h2")
def index_businessname(request):
all_BusinessNames = BusinessName.objects.all()
html = ''
for bn in all_BusinessNames:
url = '/businessname/' + str(bn.id) + '/'
html += '' + bn.FullName + '<br>'
return HttpResponse(html)
def detail_businessnames(request, bn_id):
return HttpResponse("<h2>Details for Business Names ID:" + str(bn_id) + "</h2")
def index_individuals(request):
all_individuals = Individuals.objects.all()
html = ''
for i in all_individuals:
url = '/individuals/' + str(i.id) + '/'
html += '' + i.FullName + '<br>'
return HttpResponse(html)
def detail_individuals(request, i_id):
return HttpResponse("<h2>Details for Individual Names ID:" + str(i_id)+ "</h2")
Thank you in advance,
Cohen
Include pk in your url.
Change your url like this,
url(r'(?P<pk>\d+)/$', views.index, name='index'),
instead of,
# /batches/
url(r'^$', views.index, name='index'),
OR,
if you are not passing pk to views then remove pk from index view as showned below.
def index(request):
all_Batches = Batches.objects.all()
html = ''
for batch in all_Batches:
url = '/batches/' + str(batch.id) + '/'
html += '' + str(batch.BatchNumber)+ '<br>'
return HttpResponse(html)
There are two arguments for the index view. The URL that you have written only gives request. You must give pk as an input just like the detail URL
Your url /batches/ has no parameter. So,
Your index view should be
def index(request):
# ......

Django: HTTP error 410 (Gone) with RedirectView

I get an HTTP 410 error when invoking the following Django View:
>>> views.py:
class ReopenMilestoneView(
dj_auth_mixins.LoginRequiredMixin, dj_views.RedirectView
):
pattern_name = 'bibliotheka_dashboard'
def dispatch(self, request, *args, **kwargs):
print('DISPATCH BEGIN')
instance = project_models.Milestone.objects.get(pk=kwargs['pk'])
instance.state = project_models.STATE_OPEN
instance.save()
print('DISPATCH END')
return super(ReopenMilestoneView, self).dispatch(
request, *args, **kwargs
)
def http_method_not_allowed(self, *args, **kwargs):
print('HTTP NOT ALLOWED BEGIN')
try:
return super(ReopenMilestoneView, self).http_method_not_allowed(
*args, **kwargs
)
except:
print('EXCEPTION')
print('HTTP NOT ALLOWED END')
def get_redirect_url(self, *args, **kwargs):
print('REDIRECT BEGIN')
result = super(ReopenMilestoneView, self).get_redirect_url(
*args, **kwargs
)
print('REDIRECT END, result = ' + str(result))
url = urlresolvers.reverse('bibliotheka_dashboard')
url2 = urlresolvers.reverse(self.pattern_name)
print('REDIRECT END, URL_resolved = ' + str(url))
print('REDIRECT END, pattern_name = ' + str(self.pattern_name))
print('REDIRECT END, URL_2_resolved = ' + str(url2))
return result
>>> urls.py:
...
url(
r'^milestone/dashboard/$',
project_views.MilestoneDashboard.as_view(),
name='milestone_dashboard'
),
url(
r'^milestone/(?P<pk>[\w-]+)/dashboard/$',
project_views.MilestoneDashboard.as_view(),
name='milestone_specific_dashboard'
),
...
I added prints through the three methods form "RedirectView" that are mentioned in the Django documentation as part of the regular workflow (django).
Dispatch is properly executed but, when resolving automatically the "pattern_name", "RedirectView" fails... manually resolving it, solves the problem.
DISPATCH BEGIN
DISPATCH END
REDIRECT BEGIN
REDIRECT END, result = None
REDIRECT END, URL_resolved = /
REDIRECT END, pattern_name = bibliotheka_dashboard
REDIRECT END, URL_2_resolved = /
Gone: /prj/milestone/2/reopen/
[12/Jul/2017 13:28:34] "GET /prj/milestone/2/reopen/ HTTP/1.1" 410 0
I have used "RedirectView" before but I have never got this error, any ideas? Django is not returning a lot of info back...
My URLs are defined as follows:
from django.conf.urls import url, include
from django.conf.urls import static as dj_static
from django.contrib import admin
from bibliotheka import settings as bibliotheka_settings
from documentation.views import project as project_views
urlpatterns = [
url(
r'^$',
project_views.MilestoneDashboard.as_view(),
name='bibliotheka_dashboard'
),
url(r'^admin/', admin.site.urls),
url(r'^accounts/', include('accounts.urls')),
url(r'^accounts/', include('allauth.urls')),
url(r'^prj/', include('documentation.urls.project')),
url(r'^dox/', include('documentation.urls.documents')),
url(r'^dox/', include('documentation.urls.discrepancies')),
]
if bibliotheka_settings.DEBUG:
urlpatterns += dj_static.static(
bibliotheka_settings.MEDIA_URL,
document_root=bibliotheka_settings.MEDIA_ROOT
)
I am trying to redirect to "/" with the problematic views.
Django is failing to reverse milestone_dashboard. In Django <= 1.11, it silences the NoReverseMatch, and returns a 410 response.
This behaviour has been changed in Django 2.0 (see ticket 26911), so Django will no longer silence the exception.
When you use pattern_name, Django tries to reverse with the same args and kwargs. You do not want this, as you are redirecting from a url containing the pk to a url that does not have any arguments.
You can set url with reverse_lazy:
from django.urls import reverse_lazy
class ReopenMilestoneView(RedirectView):
url = reverse_lazy('bibliotheka_dashboard')

Unable to retrieve HTTP Post data from external API in django

I am getting error : 'str' object has no attribute 'method' . See my code below :
#csrf_exempt
def completepayment(request):
varerr =''
plist = []
if request.method == 'POST':
try:
nid = request.POST['txnref']
except MultiValueDictKeyError:
varerr ="Woops! Operation failed due to server error. Please try again later."
return render(request, 'uportal/main.html', {'varerr':varerr})
# Fetching member details
trym = Transactions.objects.get(TransRef=nid)
amount = trym.Amount
famt = int(amount * 100)
product_id = 48
salt = '4E6047F9E7FDA5638D29FD'
hash_object = hashlib.sha512(str(product_id)+str(nid)+str(famt))
hashed = hash_object.hexdigest()
url = 'https://bestng.com/api/v1/gettransaction.json?productid=pdid&transactionreference=nid&amount=famt'
raw = urllib.urlopen(url)
js = raw.readlines()
#js_object = simplejson.loads(js)
res = simplejson.dumps(js)
for item in res:
rcode = item[0]
#rdesc = item[1]
#preff = item[2]
thisresp = completepayment(rcode)
plist.append(thisresp)
else:
varerr ="Woops! Operation failed due to server error. Please try again later."
return render(request, 'uportal/main.html', {'plist':plist, 'varerr':varerr, 'completepayment':'completepayment'})
In summary I am trying to accept and use HTTP POST value from an external API. Value is showing when I inspect element but DJANGO not retrieving. Please help.
Here is my urls.py
from django.conf.urls import patterns, url
from views import *
from django.views.generic import RedirectView
urlpatterns = patterns('myproject.prelude.views',
# Home:
url(r'^$', 'home', name='home'),
#login
url(r'^login/$', 'login', name='login'),
url(r'^welcome/$', 'welcome', name='welcome'),
# Registration Portal
# Registration Portal
url(r'^uportal/$', 'uportal', name='uportal'),
url(r'^uportal/ugreg/find/$', 'findmember', name='findmember'),
url(r'^uportal/ugreg/search/$', 'searchmember', name='searchmember'),
url(r'^uportal/ugreg/$', 'ugreg', name='ugreg'),
url(r'^uportal/ugreg/initiate-payment/$', 'initiatepayment', name='initiatepayment'),
url(r'^uportal/ugreg/verifypayment/$', 'verifypayment', name='verifypayment'),
url(r'^uportal/ugreg/proceedpayment/$', RedirectView.as_view(url='https://bestng.com/pay'), name='remote_admin'),
url(r'^uportal/ugreg/completepayment/$', completepayment, name='completepayment'),
Thank you
It appears that your problem is that request is an str object rather than a request object.
Please produce urls.py and views.py.
For readability, let’s rewrite the part below:
url = 'https://bestng.com/api/v1/gettransaction.json'
params = '?productid={product_id}&transactionreference={nid}&amount={famt}'
raw = urllib.urlopen(url + params.format(**locals()))
Or even, like so:
url = 'https://bestng.com/api/v1/gettransaction.json'
params = '?productid={product_id}&transactionreference={nid}&amount={famt}'
request = url + params.format(**locals())
raw = urllib.urlopen(request)
Also, the try block is not what I would use. Instead, I would use the get method of the POST dict and return a flag value:
nid = request.POST.get('tnxref', False)
I am unable to reproduce the error you are getting. With a slightly different project-level urls.py (very simplified), the ‘completepayment’ view works fine for me. Here is urls.py.
from django.conf.urls import patterns, url
from app.views import completepayment
# The app is simply called app in my example.
urlpatterns = patterns('',
# I remove the prefix
url(r'^uportal/ugreg/completepayment/$', completepayment, name='completepayment'),
)
# This last parenthesis might be missing in your code.

Categories