Check if string matches dynamic regexp and find variables - python

In django web app, user may define urls with dynamic parameters, for example:
/users/:id
or
/posts/:postid/:commentid
now, I have given strings, for example:
/users/mysername <- it matches /users/:id - how can I exstract "myusername" from it?
/users/mysuername/something <- doesn't match
/posts/10/382 - match, extract two variables - postid and commentid
my models.py:
class Server(BaseModel):
url = models.CharField(verbose_name=_('URL'), max_length=64)
in my view, I want to compare request's PATH_INFO:
endpoint_url = request.META.get('PATH_INFO').lower().strip().lstrip('/')
lets say I have a Server model instance with url: /users/:someid
now, when request path is: /users/somestring0
I want to match it and extract variable someid to be "somestring0".
Parmeters may contain anything - except slash (/) probably.
How can I achieve something like that?

If these endpoints are registered in Django routes, maybe just use resolver ?
from django.urls import resolve
match = resolve(my_url)
print(match.args)
print(match.kwargs)

Related

Django: Getting the page an object is on

Let's say I have a class Foo. I want to know what page a particular instance of Foo will be on: eg: api.myapp.com/foos/?page=25.
Given an object:
Foo.objects.get(id=500), how can I determine what page my instance will be on?
My approach is a little bit different so you can do this,
model_ids = (list(Model.objects.values_list('id', flat=True)))
This will give you the list of the ids. After that,
get_page_number = model_ids.index(obj_id) // per_page_objects + 1
If the obj_id is 500 so the index will be 499
now if per_page_objects are 10 then it will give you page number by calculating (499 // 10 +1 = 50).
This means your object having an id 500 is on the 50th page.
I hope this will work for you.
Django by itself does not predefine which url your model will be accessed through.
The documentation says - "Django lets you design URLs however you want, with no framework limitations".
So the process is rather opposite:
you define the url (look inside urls.py) and associate it with the view to be called for processing:
from django.urls import path
from . import views
urlpatterns = [
path('foos/', views.foo_list),
path('foos/<int:id>/', views.foo_detail),
you should define the views (usually in views.py)
and inside the view you can call any models to fetch data from DB
You can implement your API with additional packages like Django Rest Framework.
It has Routers that allow you to define a set of urls at once. The following will generate URL patterns like '^foos/$' and '^foos/{pk}/$':
you register your url within the router
from rest_framework import routers
router = routers.SimpleRouter()
router.register(r'foos', FooViewSet)
you should implement FooViewSet and make sure your model is used there.

Incorrect Django URL pattern match for 2 views with the same URL structure?

I have two url patterns in Django:
urlpatterns += patterns('',
url(r'^(?P<song_name>.+)-(?P<dj_slug>.+)-(?P<song_id>.+)/$', songs.dj_song, name='dj_song'),
url(r'^(?P<song_name>.+)-(?P<artist_slug>.+)-(?P<song_id>.+)/$', songs.trending_song, name='trending_song'),
)
When I visit a URL of the first pattern, it opens it correctly. However if I try and visit a URL of the second pattern, it tries to access the first view again. The variables song_name, dj_slug, artist_slugare strings and song_id is an integer.
What should be the URL patterns for such a case with similar URL structure?
Both urls use the same regex. I removed the group names and get:
url(r'^(.+)-(.+)-(.+)/$', songs.dj_song, name='dj_song'),
url(r'^(.+)-(.+)-(.+)/$', songs.trending_song, name='trending_song'),
Of course django uses the first match.
You should use different urls for different views. For example add the prefix to the second url:
url(r'^trending/(?P<song_name>.+)-(?P<artist_slug>.+)-(?P<song_id>.+)/$',
songs.trending_song, name='trending_song'),

django urls named groups

I want to match any url with a numeric id (various length) at the end and pass that id to a view function.
My urls are in this form:
/event/dash-separated-strings-2014-12-16-342614/
The id is 342614. The content before the date is also various.
Here is my url config:
url(r'^event/(*.-\d{4}-\d{2}-\d{2}-)(?P<event_id>\d*)/$', view_event , name='my_view_event')
The problem is that the full url is passed to my view function. What i want is the named group only. What is wrong with my config?
Try this:
url(r'^event/[\w\-]+-\d{4}-\d{2}-\d{2}-(?P<event_id>\d+)/$', view_event , name='my_view_event')

Django URL Variables - Business Name in URL in stead of ID

Trying to pass Business Name in URL in stead of ID. When I pass IDs, everything is fine.
urls.py
url(r'^(?P<name>\w+)/$', 'views.business'),
views.py
def business(request, name=1):
return render_to_response('business.html',
{'business': business.objects.get(name=name) })
template.html
Name{{ business.name }}
When I do this, it will only work for single word business name such as "Bank" however if the business has multiple words "Wells Fargo" it will not work.
My goal is to use slugify to pass short SEO friendly URL such as
http://website.com/business-name/
Thanks for your time and for your help!
Accordint to re module docs \w:
matches any alphanumeric character and the underscore
and the url you are trying to match has a dash because django's slugify method converts spaces and some non-ascii chars into dashes. So the fix consists in modifying the urls.py pattern to:
url(r'^(?P<name>[\w-]+)/$', 'views.business'),
But this isn't enough. Your current view will try to get a Business instance with the slugified name and will throw a DoesNotExists exception. So you should do one of the folowing things:
Add an slug field to your Business model which value must be slugify(business.name)
or add an id to the url, like this:
url(r'^(?P[\w-]+)/(?P\d+)/$', 'views.business'),
and modify your view to get the instance by id:
def business(request, name, obj_id):
return render_to_response('business.html', {'business': business.objects.get(id=obj_id) })
First of all, you need to allow dashes in your url configuration:
url(r'^(?P<name>[-\w]+)/$', 'views.business'),
[-\w]+ matches "alphanumeric" characters in any case, underscore (_) and a dash.
Also, in the view, you need to "unslugify" the value passed in:
def business(request, name='unknown'):
name = name.replace('-', ' ').capitalize()
return render_to_response('business.html',
{'business': business.objects.get(name=name) })
Also see:
My Django URLs not picking up dashes
docs on slugify
How do I create a slug in Django?
Hope that helps.

Creating a "catch all" for URLs with Python's Flask

I want to create custom URLs for each user on my site.
My application uses certain custom URLs for its internal pages:
/login
/gallery
/about
etc ...
How can I make a url that would come after the above urls, and supply a function urlLookup() with the string it contains? And would I have to declare this at the end of my views file?
For example:
/First-Last
And how could I extend this to multiple variables?
/First-Last/contact
/First-Last/album/photo-title
Use url variables:
#app.route("/<full_name>")
def profile(full_name):
# Lookup user by full name
#app.route("/<full_name>/<action>", defaults={"action": "contact"})
def act_on_user(full_name, action):
# Lookup user and act on them

Categories