1

I have a question regarding generating example urls according the Django url and path.

For example if I have 2 urls like:

 path('example/<int:example_id>/', views.some_view, name='example')

 url(r'^example/(?P<example_id>[0-9]+)/$', views.some_view, name='example')


Is it possible to generate somehow by Django built-in means example full-urls for tests like:

example/234/
example/93/
example/228/
etc…

randomly.

For different urls based on concrete name + regex or converter parameters?

In other words where in source code Django understands that <int:example_id> is an integer and so on. If I have something like : 1) I expect example/ 2) I expect int - I would be able to use it to generate random example url.

Hopefully this is clear...

These urls are just an example. Real urls will differ.

Thank you.

3
  • 1
    This simply boils down to substituting it to a regex: github.com/django/django/blob/master/django/urls/… and then when the parameters are captures automatically call to_python on the string capture: github.com/django/django/blob/master/django/urls/… Commented Dec 22, 2020 at 17:45
  • 1
    As for generating random URLs, it is not said that there exists an object behind this example_id, so the URLs you generate eventually can lead to a 404 by the view. Commented Dec 22, 2020 at 17:47
  • 1
    But for a regex, you can generate random strings, especially since this eventually boils down to a finite state machine. Commented Dec 22, 2020 at 17:47

1 Answer 1

1

In other words where in source code Django understands that <int:example_id> is an integer and so on.

This is in essence looking for <…:…> patterns in the path. Django has furthermore a set of path converters. The standard ones are int, str, slug, uuid, path, but you can define your own path converters. Indeed, the Django documentation has a section registering custom path converters that explains how you can design your own path converters.

What a path basically does is constructing a regex. It thus searches for patterns like <int:example_id>. Since you here used int, the IntConverter [GitHUb] is used:

class IntConverter:
    regex = '[0-9]+'

    def to_python(self, value):
        return int(value)

    def to_url(self, value):
        return str(value)

Here it will thus replace the <int:example_id> by (?<example_id>[0-9]+), where the regex part thus will be used.

A path(…) does not only constructs a regex. It also automatically maps the captured items to a Python object by calling .to_python(…). This thus means that if you work with re_path(r'^example/(?P<example_id>[0-9]+)/$', …), then example_id will be a string, but for path('example/<int:example_id>/', …), it will automatically call int(…) on the captured string, and thus pass an int object. Often that does not make much difference.

This also holds when you serialize an object: you can pass a value, and it will call .to_url(…) on the object to convert it to a string representation for the generated URL. This thus means that you can write custom path converters that thus perform more sophisticated conversions.

I expect example/ 2) I expect int - I would be able to use it to generate random example url.

Well eventually it boils down to a regular expression. A regular expression can be converted into a finite state machine, so we can generate random valid strings. For example exrex [GitHub] is capable to generate all valid strings (this is often an generator that will keep proposing new strings), or random strings that match the regular expression. It is however not said that because it matches the path(…), that it will be sensical for the view. If you for example use this int as the primary key of a Post object it is fetching, then for random URLs, it is likely that you will generate URLs for non-existing Posts.

Sign up to request clarification or add additional context in comments.

1 Comment

very fruitfull explanation. Thanks a lot

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.