Check if a parameter exists in Django URL - python

I am trying to get a URL if it exists in the URL but keep getting the following error:
django.utils.datastructures.MultiValueDictKeyError: 'sc'
The case is that the urls can be sometimes like the following:
/allot-graph/
and sometimes:
/allot-graph/?sc='foo'
and in my function I am doing this:
class AllotmentbyMonth(APIView):
def get(self, request):
q = request.GET['sc']
if q:
print("q", q)
dataset = some query
else:
dataset = some query

When a URL is like /allot-graph/?sc='foo', you would use q=request.GET.get('sc' , '').
sc is the parameter you want, and '' is the default value if sc isn't found.
Another way to proceed is to use URLconf, then your captures from the regex are passed to the function as arguments (or named arguments).
Such as:
(r'^ allot-graph/(?P< sc >\w{0,50})/$', views.profile_page,)
Then in your views.py you would have
def profile_page(request, sc):
# Rest of the method

Related

Why does the URL string of my API filter have a forward slash instead of an equal sign? [duplicate]

Could you please explain to me why in FastAPI the following works:
#app.post("/items/v1/cards{sku}")
async def create_item(sku: str):
return {"status":200,"sku":sku} # returns status:200 and sku
but, the same endpoint with questionmark in it like the one given below does not?
#app.post("/items/v1/cards?{sku}")
async def create_item(sku: str):
return {"sku":sku} # returns 404
In the first code snippet, you defined the parameter as a Path parameter and worked as expected.
#app.post('/items/v1/cards/{sku}')
async def create_item(sku: str):
return {'sku': sku}
URL Example:
http://127.0.0.1:8000/items/v1/cards/something
In the second one, however, you attempted to pass a Query parameter in the wrong way. As per the documentation:
When you declare other function parameters that are not part of the
path parameters, they are automatically interpreted as "query"
parameters.
Hence, your endpoint should look like this:
#app.post('/items/v1/cards')
async def create_item(sku: str):
return {'sku': sku}
The query is the set of key-value pairs that go after the ? in a URL,
separated by & characters.
URL Example:
http://127.0.0.1:8000/items/v1/cards?sku=something

Flask redirect to url and pass query strings

I have a view that is defined like such:
#views.route('/issues')
def show_view():
action = request.args.get('action')
method = getattr(process_routes, action)
return method(request.args)
in my process_routes module, I would like to call this method, and pass query string values. I have the following code:
return redirect(url_for('views.show_view', action='create_or_update_success'))
I have a function in process_routes named create_or_update_success
I am getting
BuildError: ('views.show_view', {'action': 'create_or_update_success'}, None)
views is a blueprint. I can successfully call
/issues?action=create_or_update_success
In my browser.
What am I doing wrong?
The first part, views., has to reflect the first argument you give to your Blueprint() object exactly.
Don't be tempted to set that first argument to __name__, as that is likely to contain the full path of the module when inside a package. In your case I suspect that to be some_package.views rather than just views.
Use a string literal for the Blueprint() first argument instead:
views_blueprint = Blueprint('views', __name__)
so you can refer to url_for('views.show_view') without getting build errors.

Loop using app.route on Python

I'm trying to create several URLs on my serv thanks to a loop . The issue is that each function I create in a app.route can't have the same name than the others . And I don't know how to create different function names ...
Here is the code :
json_tweets = []
for line in open('C:\Users\Benjamin\Desktop\DashboardProject\last_rated_set.json',"r"):
json_tweets.append(json.loads(line,"ISO-8859-1"))
cashtag_tab = []
for tweet in json_tweets:
if not(tweet['cashtag'] in cashtag_tab) :
cashtag_tab.append(tweet['cashtag'])
for i in range(0,(len(cashtag_tab)-1)) :
var=cashtag_tab[i]
#app.route("/"+var)
def company(var) :
finance=Share(var)
datas = finance.get_historical('2014-01-01', '2014-12-31')
datas = json.dumps(datas, default=json_util.default)
return datas
I'm getting the error AssertionError : View function mapping is overwritting an existing endpoint function : company
This fails because Flask derives the endpoint name from the function by default, but it would anyway fail later because the function company requires an argument var and the route is not parameterised. The simplest option would be just checking the value inside the handler:
#api.route('/<var>')
def company(var):
if var not in cashtag_tab:
abort(404)
If you want all the routes to be in the routing map for any reason, I once needed a similar thing and came up with something like this:
def url_family(source, methods=('GET',)):
def decorator(f):
for entry in source:
# create a handler that delegates to your function
def view_func(entry=entry, **kwargs):
return f(entry, **kwargs)
endpoint = '{0}_{1}'.format(f.__name__, entry)
url = '/{0}'.format(entry)
api.add_url_rule(url,
methods=methods,
endpoint=endpoint,
view_func=view_func)
return decorator
Then you register the handlers as:
#url_family(cashtag_tab)
def company(var):
...
Assuming that you are using flask now, you should consider Custom URL Converter. Check links below
http://flask.pocoo.org/docs/0.10/api/#flask.Flask.url_map - url_map UrlConverter API
https://exploreflask.com/views.html#url-converters - example url converter
https://stackoverflow.com/a/5872904/3451543 - RegexConverter by Philip Southam
Anyway, specifying more details on your question is always helpful to get accurate answer :)

Handle optional url parameter in Django unit test case

I have created a Dynamic Url with optional parameter
e.g., If my url is as www.example.com/getTest/1/
Now this 1 in url is optional , to handle this in views I have used None like
def function(request, id=None):
pass
Thus if there is no id in URL then still the function works for me.
But I am facing issue while testing this in unit cases.
if I use url as url = reverse('yescourse:academypage_url', args=[None]) it gives me the error
NoReverseMatch: Reverse for 'academypage_url' with arguments '('new', None)' and keyword arguments '{}' not found.
So Please Tell me how I can handle these optional url in Test cases or in Reverse.
Edit :
url(r'^getTest/(?P<action>\w+)/(?P<id>\d*)$', 'app.views.create_edit_academypage', name='academypage_url'),
You made the view function's id parameter optional, but it's not optional in the url pattern. You firsty need to rewrite your pattern as :
r'^getTest/(?P<action>\w+)/(?P<id>\d+)?$'
=> the whole 'id' sub-pattern is optional, but if it's not it must match one or more numerics.
Once done, you can reverse the url by not passing any of the args nor kwargs arguments:
url = reverse('yescourse:academypage_url')
or by passing an empty list
url = reverse('yescourse:academypage_url', args=[])
or by passing None
url = reverse('yescourse:academypage_url', args=None)
but not by passing a list containing None.

Variable Route Not Working in For Loop

I tried to create multiple routes in one go by using the variables from the database and a for loop.
I tried this
temp = "example"
#app.route("/speaker/<temp>")
def getSpeakerAtr(temp):
return '''%s''' % temp
It works very well. BUT:
for x in models.Speaker.objects:
temp = str(x.name)
#app.route("/speaker/<temp>")
def getSpeakerAtr(temp):
return '''%s''' % temp
Doesn't work. The error message:
File "/Users/yang/Documents/CCPC-Website/venv/lib/python2.7/site-packages/flask/app.py", line 1013, in decorator
02:03:04 web.1 | self.add_url_rule(rule, endpoint, f, **options)
**The reason I want to use multiple routes is that I need to get the full data of an object by querying from the route. For example:
if we type this url:
//.../speaker/sam
we can get the object who has the 'name' value as 'sam'. Then I can use all of the values in this object like bio or something.**
You don't need multiple routes. Just one route that validates its value, eg:
#app.route('/speaker/<temp>')
def getSpeakerAtr(temp):
if not any(temp == str(x.name) for x in models.Speaker.objects):
# do something appropriate (404 or something?)
# carry on doing something else
Or as to your real intent:
#app.route('/speaker/<name>')
def getSpeakerAtr(name):
speaker = # do something with models.Speaker.objects to lookup `name`
if not speaker: # or whatever check is suitable to determine name didn't exist
# raise a 404, or whatever's suitable
# we have a speaker object, so use as appropriate

Categories

Resources