Mock Version: 2.16 ENTER ['do_with_status'](['bash', '--login', '-c', '/usr/bin/rpmbuild -bs --target x86_64 --nodeps /builddir/build/SPECS/python-djurl.spec'], chrootPath='/var/lib/mock/fedora-rawhide-x86_64-1646296368.101088/root'env={'TERM': 'vt100', 'SHELL': '/bin/bash', 'HOME': '/builddir', 'HOSTNAME': 'mock', 'PATH': '/usr/bin:/bin:/usr/sbin:/sbin', 'PROMPT_COMMAND': 'printf "\\033]0;\\007"', 'PS1': ' \\s-\\v\\$ ', 'LANG': 'C.UTF-8'}shell=Falselogger=timeout=0uid=1000gid=135user='mockbuild'nspawn_args=['--capability=cap_ipc_lock', '--rlimit=RLIMIT_NOFILE=10240', '--capability=cap_ipc_lock', '--bind=/tmp/mock-resolv.46fwcqyf:/etc/resolv.conf', '--bind=/dev/btrfs-control', '--bind=/dev/loop-control', '--bind=/dev/loop0', '--bind=/dev/loop1', '--bind=/dev/loop2', '--bind=/dev/loop3', '--bind=/dev/loop4', '--bind=/dev/loop5', '--bind=/dev/loop6', '--bind=/dev/loop7', '--bind=/dev/loop8', '--bind=/dev/loop9', '--bind=/dev/loop10', '--bind=/dev/loop11']unshare_net=TrueprintOutput=True) Using nspawn with args ['--capability=cap_ipc_lock', '--rlimit=RLIMIT_NOFILE=10240', '--capability=cap_ipc_lock', '--bind=/tmp/mock-resolv.46fwcqyf:/etc/resolv.conf', '--bind=/dev/btrfs-control', '--bind=/dev/loop-control', '--bind=/dev/loop0', '--bind=/dev/loop1', '--bind=/dev/loop2', '--bind=/dev/loop3', '--bind=/dev/loop4', '--bind=/dev/loop5', '--bind=/dev/loop6', '--bind=/dev/loop7', '--bind=/dev/loop8', '--bind=/dev/loop9', '--bind=/dev/loop10', '--bind=/dev/loop11'] Executing command: ['/usr/bin/systemd-nspawn', '-q', '-M', 'c11da1c0416b491e94a2c1665ee602ce', '-D', '/var/lib/mock/fedora-rawhide-x86_64-1646296368.101088/root', '-a', '-u', 'mockbuild', '--capability=cap_ipc_lock', '--rlimit=RLIMIT_NOFILE=10240', '--capability=cap_ipc_lock', '--bind=/tmp/mock-resolv.46fwcqyf:/etc/resolv.conf', '--bind=/dev/btrfs-control', '--bind=/dev/loop-control', '--bind=/dev/loop0', '--bind=/dev/loop1', '--bind=/dev/loop2', '--bind=/dev/loop3', '--bind=/dev/loop4', '--bind=/dev/loop5', '--bind=/dev/loop6', '--bind=/dev/loop7', '--bind=/dev/loop8', '--bind=/dev/loop9', '--bind=/dev/loop10', '--bind=/dev/loop11', '--console=pipe', '--setenv=TERM=vt100', '--setenv=SHELL=/bin/bash', '--setenv=HOME=/builddir', '--setenv=HOSTNAME=mock', '--setenv=PATH=/usr/bin:/bin:/usr/sbin:/sbin', '--setenv=PROMPT_COMMAND=printf "\\033]0;\\007"', '--setenv=PS1= \\s-\\v\\$ ', '--setenv=LANG=C.UTF-8', '--resolv-conf=off', 'bash', '--login', '-c', '/usr/bin/rpmbuild -bs --target x86_64 --nodeps /builddir/build/SPECS/python-djurl.spec'] with env {'TERM': 'vt100', 'SHELL': '/bin/bash', 'HOME': '/builddir', 'HOSTNAME': 'mock', 'PATH': '/usr/bin:/bin:/usr/sbin:/sbin', 'PROMPT_COMMAND': 'printf "\\033]0;\\007"', 'PS1': ' \\s-\\v\\$ ', 'LANG': 'C.UTF-8', 'SYSTEMD_NSPAWN_TMPFS_TMP': '0', 'SYSTEMD_SECCOMP': '0'} and shell False Building target platforms: x86_64 Building for target x86_64 setting SOURCE_DATE_EPOCH=1645920000 Wrote: /builddir/build/SRPMS/python-djurl-0.2.0-1.fc37.src.rpm Child return code was: 0 ENTER ['do_with_status'](['bash', '--login', '-c', '/usr/bin/rpmbuild -br --target x86_64 --nodeps /builddir/build/SPECS/python-djurl.spec'], chrootPath='/var/lib/mock/fedora-rawhide-x86_64-1646296368.101088/root'env={'TERM': 'vt100', 'SHELL': '/bin/bash', 'HOME': '/builddir', 'HOSTNAME': 'mock', 'PATH': '/usr/bin:/bin:/usr/sbin:/sbin', 'PROMPT_COMMAND': 'printf "\\033]0;\\007"', 'PS1': ' \\s-\\v\\$ ', 'LANG': 'C.UTF-8'}shell=Falselogger=timeout=0uid=1000gid=135user='mockbuild'nspawn_args=['--capability=cap_ipc_lock', '--rlimit=RLIMIT_NOFILE=10240', '--capability=cap_ipc_lock', '--bind=/tmp/mock-resolv.46fwcqyf:/etc/resolv.conf', '--bind=/dev/btrfs-control', '--bind=/dev/loop-control', '--bind=/dev/loop0', '--bind=/dev/loop1', '--bind=/dev/loop2', '--bind=/dev/loop3', '--bind=/dev/loop4', '--bind=/dev/loop5', '--bind=/dev/loop6', '--bind=/dev/loop7', '--bind=/dev/loop8', '--bind=/dev/loop9', '--bind=/dev/loop10', '--bind=/dev/loop11']unshare_net=TrueraiseExc=FalseprintOutput=True) Using nspawn with args ['--capability=cap_ipc_lock', '--rlimit=RLIMIT_NOFILE=10240', '--capability=cap_ipc_lock', '--bind=/tmp/mock-resolv.46fwcqyf:/etc/resolv.conf', '--bind=/dev/btrfs-control', '--bind=/dev/loop-control', '--bind=/dev/loop0', '--bind=/dev/loop1', '--bind=/dev/loop2', '--bind=/dev/loop3', '--bind=/dev/loop4', '--bind=/dev/loop5', '--bind=/dev/loop6', '--bind=/dev/loop7', '--bind=/dev/loop8', '--bind=/dev/loop9', '--bind=/dev/loop10', '--bind=/dev/loop11'] Executing command: ['/usr/bin/systemd-nspawn', '-q', '-M', '18e9392e781c43209e0dc00538ad1c25', '-D', '/var/lib/mock/fedora-rawhide-x86_64-1646296368.101088/root', '-a', '-u', 'mockbuild', '--capability=cap_ipc_lock', '--rlimit=RLIMIT_NOFILE=10240', '--capability=cap_ipc_lock', '--bind=/tmp/mock-resolv.46fwcqyf:/etc/resolv.conf', '--bind=/dev/btrfs-control', '--bind=/dev/loop-control', '--bind=/dev/loop0', '--bind=/dev/loop1', '--bind=/dev/loop2', '--bind=/dev/loop3', '--bind=/dev/loop4', '--bind=/dev/loop5', '--bind=/dev/loop6', '--bind=/dev/loop7', '--bind=/dev/loop8', '--bind=/dev/loop9', '--bind=/dev/loop10', '--bind=/dev/loop11', '--console=pipe', '--setenv=TERM=vt100', '--setenv=SHELL=/bin/bash', '--setenv=HOME=/builddir', '--setenv=HOSTNAME=mock', '--setenv=PATH=/usr/bin:/bin:/usr/sbin:/sbin', '--setenv=PROMPT_COMMAND=printf "\\033]0;\\007"', '--setenv=PS1= \\s-\\v\\$ ', '--setenv=LANG=C.UTF-8', '--resolv-conf=off', 'bash', '--login', '-c', '/usr/bin/rpmbuild -br --target x86_64 --nodeps /builddir/build/SPECS/python-djurl.spec'] with env {'TERM': 'vt100', 'SHELL': '/bin/bash', 'HOME': '/builddir', 'HOSTNAME': 'mock', 'PATH': '/usr/bin:/bin:/usr/sbin:/sbin', 'PROMPT_COMMAND': 'printf "\\033]0;\\007"', 'PS1': ' \\s-\\v\\$ ', 'LANG': 'C.UTF-8', 'SYSTEMD_NSPAWN_TMPFS_TMP': '0', 'SYSTEMD_SECCOMP': '0'} and shell False Building target platforms: x86_64 Building for target x86_64 setting SOURCE_DATE_EPOCH=1645920000 Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.8Ui18h + umask 022 + cd /builddir/build/BUILD + cd /builddir/build/BUILD + rm -rf djurl-0.2.0 + /usr/bin/gzip -dc /builddir/build/SOURCES/djurl-0.2.0.tar.gz + /usr/bin/tar -xof - + STATUS=0 + '[' 0 -ne 0 ']' + cd djurl-0.2.0 + /usr/bin/chmod -Rf a+rX,u+w,g-w,o-w . + RPM_EC=0 ++ jobs -p + exit 0 Executing(%generate_buildrequires): /bin/sh -e /var/tmp/rpm-tmp.AkAsEu + umask 022 + cd /builddir/build/BUILD + cd djurl-0.2.0 + echo pyproject-rpm-macros + echo python3-devel + echo 'python3dist(pip) >= 19' + echo 'python3dist(packaging)' + '[' -f pyproject.toml ']' + '[' -f setup.py ']' + echo 'python3dist(setuptools) >= 40.8' + echo 'python3dist(wheel)' + rm -rfv '*.dist-info/' + '[' -f /usr/bin/python3 ']' + RPM_TOXENV=py310 + HOSTNAME=rpmbuild + /usr/bin/python3 -s /usr/lib/rpm/redhat/pyproject_buildrequires.py --generate-extras --python3_pkgversion 3 -r Handling setuptools >= 40.8 from default build backend Requirement not satisfied: setuptools >= 40.8 Handling wheel from default build backend Requirement not satisfied: wheel Exiting dependency generation pass: build backend + RPM_EC=0 ++ jobs -p + exit 0 Wrote: /builddir/build/SRPMS/python-djurl-0.2.0-1.fc37.buildreqs.nosrc.rpm Child return code was: 11 Dynamic buildrequires detected Going to install missing buildrequires. See root.log for details. ENTER ['do_with_status'](['bash', '--login', '-c', '/usr/bin/rpmbuild -br --target x86_64 --nodeps /builddir/build/SPECS/python-djurl.spec'], chrootPath='/var/lib/mock/fedora-rawhide-x86_64-1646296368.101088/root'env={'TERM': 'vt100', 'SHELL': '/bin/bash', 'HOME': '/builddir', 'HOSTNAME': 'mock', 'PATH': '/usr/bin:/bin:/usr/sbin:/sbin', 'PROMPT_COMMAND': 'printf "\\033]0;\\007"', 'PS1': ' \\s-\\v\\$ ', 'LANG': 'C.UTF-8'}shell=Falselogger=timeout=0uid=1000gid=135user='mockbuild'nspawn_args=['--capability=cap_ipc_lock', '--rlimit=RLIMIT_NOFILE=10240', '--capability=cap_ipc_lock', '--bind=/tmp/mock-resolv.46fwcqyf:/etc/resolv.conf', '--bind=/dev/btrfs-control', '--bind=/dev/loop-control', '--bind=/dev/loop0', '--bind=/dev/loop1', '--bind=/dev/loop2', '--bind=/dev/loop3', '--bind=/dev/loop4', '--bind=/dev/loop5', '--bind=/dev/loop6', '--bind=/dev/loop7', '--bind=/dev/loop8', '--bind=/dev/loop9', '--bind=/dev/loop10', '--bind=/dev/loop11']unshare_net=TrueraiseExc=FalseprintOutput=True) Using nspawn with args ['--capability=cap_ipc_lock', '--rlimit=RLIMIT_NOFILE=10240', '--capability=cap_ipc_lock', '--bind=/tmp/mock-resolv.46fwcqyf:/etc/resolv.conf', '--bind=/dev/btrfs-control', '--bind=/dev/loop-control', '--bind=/dev/loop0', '--bind=/dev/loop1', '--bind=/dev/loop2', '--bind=/dev/loop3', '--bind=/dev/loop4', '--bind=/dev/loop5', '--bind=/dev/loop6', '--bind=/dev/loop7', '--bind=/dev/loop8', '--bind=/dev/loop9', '--bind=/dev/loop10', '--bind=/dev/loop11'] Executing command: ['/usr/bin/systemd-nspawn', '-q', '-M', '96dfebd981f04ff28618048854b3c5a5', '-D', '/var/lib/mock/fedora-rawhide-x86_64-1646296368.101088/root', '-a', '-u', 'mockbuild', '--capability=cap_ipc_lock', '--rlimit=RLIMIT_NOFILE=10240', '--capability=cap_ipc_lock', '--bind=/tmp/mock-resolv.46fwcqyf:/etc/resolv.conf', '--bind=/dev/btrfs-control', '--bind=/dev/loop-control', '--bind=/dev/loop0', '--bind=/dev/loop1', '--bind=/dev/loop2', '--bind=/dev/loop3', '--bind=/dev/loop4', '--bind=/dev/loop5', '--bind=/dev/loop6', '--bind=/dev/loop7', '--bind=/dev/loop8', '--bind=/dev/loop9', '--bind=/dev/loop10', '--bind=/dev/loop11', '--console=pipe', '--setenv=TERM=vt100', '--setenv=SHELL=/bin/bash', '--setenv=HOME=/builddir', '--setenv=HOSTNAME=mock', '--setenv=PATH=/usr/bin:/bin:/usr/sbin:/sbin', '--setenv=PROMPT_COMMAND=printf "\\033]0;\\007"', '--setenv=PS1= \\s-\\v\\$ ', '--setenv=LANG=C.UTF-8', '--resolv-conf=off', 'bash', '--login', '-c', '/usr/bin/rpmbuild -br --target x86_64 --nodeps /builddir/build/SPECS/python-djurl.spec'] with env {'TERM': 'vt100', 'SHELL': '/bin/bash', 'HOME': '/builddir', 'HOSTNAME': 'mock', 'PATH': '/usr/bin:/bin:/usr/sbin:/sbin', 'PROMPT_COMMAND': 'printf "\\033]0;\\007"', 'PS1': ' \\s-\\v\\$ ', 'LANG': 'C.UTF-8', 'SYSTEMD_NSPAWN_TMPFS_TMP': '0', 'SYSTEMD_SECCOMP': '0'} and shell False Building target platforms: x86_64 Building for target x86_64 setting SOURCE_DATE_EPOCH=1645920000 Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.p6bOLC + umask 022 + cd /builddir/build/BUILD + cd /builddir/build/BUILD + rm -rf djurl-0.2.0 + /usr/bin/gzip -dc /builddir/build/SOURCES/djurl-0.2.0.tar.gz + /usr/bin/tar -xof - + STATUS=0 + '[' 0 -ne 0 ']' + cd djurl-0.2.0 + /usr/bin/chmod -Rf a+rX,u+w,g-w,o-w . + RPM_EC=0 ++ jobs -p + exit 0 Executing(%generate_buildrequires): /bin/sh -e /var/tmp/rpm-tmp.vpYzYU + umask 022 + cd /builddir/build/BUILD + cd djurl-0.2.0 + echo pyproject-rpm-macros + echo python3-devel + echo 'python3dist(pip) >= 19' + echo 'python3dist(packaging)' + '[' -f pyproject.toml ']' + '[' -f setup.py ']' + echo 'python3dist(setuptools) >= 40.8' + echo 'python3dist(wheel)' + rm -rfv '*.dist-info/' + '[' -f /usr/bin/python3 ']' + RPM_TOXENV=py310 + HOSTNAME=rpmbuild + /usr/bin/python3 -s /usr/lib/rpm/redhat/pyproject_buildrequires.py --generate-extras --python3_pkgversion 3 -r Handling setuptools >= 40.8 from default build backend Requirement satisfied: setuptools >= 40.8 (installed: setuptools 59.6.0) Handling wheel from default build backend Requirement satisfied: wheel (installed: wheel 0.37.0) /usr/lib/python3.10/site-packages/setuptools/dist.py:723: UserWarning: Usage of dash-separated 'description-file' will not be supported in future versions. Please use the underscore name 'description_file' instead warnings.warn( HOOK STDOUT: running egg_info HOOK STDOUT: writing djurl.egg-info/PKG-INFO HOOK STDOUT: writing dependency_links to djurl.egg-info/dependency_links.txt HOOK STDOUT: writing requirements to djurl.egg-info/requires.txt HOOK STDOUT: writing top-level names to djurl.egg-info/top_level.txt HOOK STDOUT: reading manifest file 'djurl.egg-info/SOURCES.txt' HOOK STDOUT: reading manifest template 'MANIFEST.in' HOOK STDOUT: writing manifest file 'djurl.egg-info/SOURCES.txt' HOOK STDOUT: ![DjUrl - Django urls](/djurlheader.png) [![Build Status](https://travis-ci.org/venturachrisdev/djurl.svg?branch=master)](https://travis-ci.org/venturachrisdev/djurl) HOOK STDOUT: === HOOK STDOUT: Simple yet helpful library for writing Django urls by an easy, short an intuitive way. HOOK STDOUT: HOOK STDOUT: Why should I use DjUrl? HOOK STDOUT: --- HOOK STDOUT: Django routing urls aren't easy to deal with, regular expressions can become a nightmare sometimes. Just imagine dealing with such routes in your `django app`: HOOK STDOUT: ```python HOOK STDOUT: from django.conf.urls import url HOOK STDOUT: from core import BlogView, SinglePostView, SearchResultsView, ArchiveView HOOK STDOUT: HOOK STDOUT: urlpatterns = [ HOOK STDOUT: # => /blog/ HOOK STDOUT: url(r'^blog/$', BlogView.as_view(), name="blog"), HOOK STDOUT: # => /blog/5 HOOK STDOUT: url(r'^blog/(?P[0-9]+)/$', SinglePostView.as_view(), name="singlepost"), HOOK STDOUT: # => /blog/search/sometitle HOOK STDOUT: url(r'^blog/search/(?P[A-Za-z0-9_-]+)/$', SearchResultsView.as_view(), name="search"), HOOK STDOUT: # => /blog/archive/2017/02/12 HOOK STDOUT: url(r'^blog/archive/(?P[0-9]{4}-(0?([1-9])|10|11|12)-((0|1|2)?([1-9])|[1-3]0|31))/$', HOOK STDOUT: ArchiveView.as_view(), name="archive") HOOK STDOUT: ] HOOK STDOUT: ``` HOOK STDOUT: That's too much work and you lost me in those regex. With **DjUrl** this comes easy, you just need to *express what you want*, **DjUrl will handle the regular expressions for you**: HOOK STDOUT: HOOK STDOUT: ```python HOOK STDOUT: from djurl import url HOOK STDOUT: from core import BlogView, SinglePostView, SearchResultsView, ArchiveView HOOK STDOUT: HOOK STDOUT: urlpatterns = [ HOOK STDOUT: url('/blog', BlogView, name="blog"), HOOK STDOUT: url('/blog/:id', SinglePostView, name="singlepost"), HOOK STDOUT: url('/blog/search/:query', SearchResultsView, name="search"), HOOK STDOUT: url('/blog/archive/:date', ArchiveView, name="archive") HOOK STDOUT: ] HOOK STDOUT: ``` HOOK STDOUT: No regex, just clean paths and param names. You can now pass the regex work to DjUrl and concentrate in the *bussiness logic*. It saves you a lot of time and code. *You don't need to worry about the routes anymore*. **Note you don't need to call `as_view` in your CBV's.** DjUrl does this for you as well. HOOK STDOUT: HOOK STDOUT: Usage HOOK STDOUT: --- HOOK STDOUT: Now you know what you should use `DjUrl`, It's time to learn how to use it. DjUrl has a list of known/default pattern that you can use in your routes, these are: HOOK STDOUT: HOOK STDOUT: * `id`: A secuence of characters from 0 to 9. Ej: `1, 12, 454545, 8885500, 8` HOOK STDOUT: * `pk`: A primary key, it's like `id` but needed for `Class Based Views`. HOOK STDOUT: * `page`: falls in the same category, but you'd use `page` for a better param name. HOOK STDOUT: * `slug`: A simple string (alphanumeric characters). HOOK STDOUT: * `query`: A search parameter. It allows some special characters that *slug* doesn't. Ex: `hello%20word`, `don%27t_quote-me` HOOK STDOUT: * `day`: A number between 01,..., 31. HOOK STDOUT: * `month`: A number between 01,...,12. HOOK STDOUT: * `year`: A four digits number: `1998, 2017, 2018, 3015, 2020, 1406...` HOOK STDOUT: * `date`: An expression with `year-month-day` format: `2017-06-23, 1998-10-20, 1492-10-12` HOOK STDOUT: * `filename`: An expression with `*.\w{2,4}` format: `index.js`, `detail.html`, `'my_book.pdf'`, `'dfj358h-g9854-fn84n4.tmp'` HOOK STDOUT: * `UUID`: *Universally unique identifier* is a 128-bit number used to identify information in computer systems. Use a format as `xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx`. Ex: `123e4567-e89b-12d3-a456-426655440000` HOOK STDOUT: HOOK STDOUT: That means, wherever you put `/:id` you can use it in your view as param (named `id`). HOOK STDOUT: ```python HOOK STDOUT: url('post/:pk/comment/:id', myview, name="post_comment") HOOK STDOUT: ``` HOOK STDOUT: Your view: HOOK STDOUT: ```python HOOK STDOUT: def myview(request, pk, id): HOOK STDOUT: # Use `pk` (post's) and `id` (comment's) HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: But what if I have two or more id's, or two slugs? What if I wanted to use a custom name for my id's? - Ok, you can use custom names if you end it with `_` + the pattern type. - What?... HOOK STDOUT: ```python HOOK STDOUT: url('post/:post_pk/comment/:comment_id', myview, ...) HOOK STDOUT: # ... HOOK STDOUT: def myview(request, post_pk, comment_id): HOOK STDOUT: # `post_pk` is parsed as a :pk and `comment_id` like an :id HOOK STDOUT: HOOK STDOUT: ``` HOOK STDOUT: Yeah, it sounds good!, but... What if I wanted to use my own patterns? - Easy, any world in the path is of type `:slug` by default, but if you need a custom pattern you can register many as you want: HOOK STDOUT: ```python HOOK STDOUT: from djurl import url, register_pattern HOOK STDOUT: register_pattern('hash', '[a-f0-9]{9}') HOOK STDOUT: # parsed as slug HOOK STDOUT: url('/:user', myUserView), HOOK STDOUT: # custom pattern HOOK STDOUT: url('/:hash', myview), HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: If you have questions, visit our [FAQ's](FAQ.md) or open an *issue*. HOOK STDOUT: HOOK STDOUT: Install HOOK STDOUT: --- HOOK STDOUT: If you want to have fun with this library and integrate it to your project, just type in your terminal: HOOK STDOUT: ``` HOOK STDOUT: $ pip install djurl HOOK STDOUT: ``` HOOK STDOUT: or, clone the repo and type: HOOK STDOUT: ``` HOOK STDOUT: $ python setup.py install HOOK STDOUT: ``` HOOK STDOUT: Enjoy it! HOOK STDOUT: HOOK STDOUT: Testing HOOK STDOUT: --- HOOK STDOUT: Clone the repo and run Djurl tests by: HOOK STDOUT: ``` HOOK STDOUT: $ python setup.py test HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: Contributions HOOK STDOUT: --- HOOK STDOUT: If you've found a bug/error or just have questions, feel free to open an **issue**. And, **Pull requests** are welcome as well. HOOK STDOUT: Don't forget to add your name to [CONTRIBUTORS.md](CONTRIBUTORS.md) HOOK STDOUT: HOOK STDOUT: License HOOK STDOUT: ======= HOOK STDOUT: HOOK STDOUT: Copyright 2017 Christopher Ventura HOOK STDOUT: HOOK STDOUT: Licensed under the Apache License, Version 2.0 (the "License"); HOOK STDOUT: you may not use this file except in compliance with the License. HOOK STDOUT: You may obtain a copy of the License at HOOK STDOUT: HOOK STDOUT: http://www.apache.org/licenses/LICENSE-2.0 HOOK STDOUT: HOOK STDOUT: Unless required by applicable law or agreed to in writing, software HOOK STDOUT: distributed under the License is distributed on an "AS IS" BASIS, HOOK STDOUT: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. HOOK STDOUT: See the License for the specific language governing permissions and HOOK STDOUT: limitations under the License. HOOK STDOUT: Handling wheel from get_requires_for_build_wheel Requirement satisfied: wheel (installed: wheel 0.37.0) HOOK STDOUT: running dist_info HOOK STDOUT: writing djurl.egg-info/PKG-INFO HOOK STDOUT: writing dependency_links to djurl.egg-info/dependency_links.txt HOOK STDOUT: writing requirements to djurl.egg-info/requires.txt HOOK STDOUT: writing top-level names to djurl.egg-info/top_level.txt HOOK STDOUT: reading manifest file 'djurl.egg-info/SOURCES.txt' HOOK STDOUT: reading manifest template 'MANIFEST.in' HOOK STDOUT: writing manifest file 'djurl.egg-info/SOURCES.txt' HOOK STDOUT: creating '/builddir/build/BUILD/djurl-0.2.0/djurl.dist-info' HOOK STDOUT: ![DjUrl - Django urls](/djurlheader.png) [![Build Status](https://travis-ci.org/venturachrisdev/djurl.svg?branch=master)](https://travis-ci.org/venturachrisdev/djurl) HOOK STDOUT: === HOOK STDOUT: Simple yet helpful library for writing Django urls by an easy, short an intuitive way. HOOK STDOUT: HOOK STDOUT: Why should I use DjUrl? HOOK STDOUT: --- HOOK STDOUT: Django routing urls aren't easy to deal with, regular expressions can become a nightmare sometimes. Just imagine dealing with such routes in your `django app`: HOOK STDOUT: ```python HOOK STDOUT: from django.conf.urls import url HOOK STDOUT: from core import BlogView, SinglePostView, SearchResultsView, ArchiveView HOOK STDOUT: HOOK STDOUT: urlpatterns = [ HOOK STDOUT: # => /blog/ HOOK STDOUT: url(r'^blog/$', BlogView.as_view(), name="blog"), HOOK STDOUT: # => /blog/5 HOOK STDOUT: url(r'^blog/(?P[0-9]+)/$', SinglePostView.as_view(), name="singlepost"), HOOK STDOUT: # => /blog/search/sometitle HOOK STDOUT: url(r'^blog/search/(?P[A-Za-z0-9_-]+)/$', SearchResultsView.as_view(), name="search"), HOOK STDOUT: # => /blog/archive/2017/02/12 HOOK STDOUT: url(r'^blog/archive/(?P[0-9]{4}-(0?([1-9])|10|11|12)-((0|1|2)?([1-9])|[1-3]0|31))/$', HOOK STDOUT: ArchiveView.as_view(), name="archive") HOOK STDOUT: ] HOOK STDOUT: ``` HOOK STDOUT: That's too much work and you lost me in those regex. With **DjUrl** this comes easy, you just need to *express what you want*, **DjUrl will handle the regular expressions for you**: HOOK STDOUT: HOOK STDOUT: ```python HOOK STDOUT: from djurl import url HOOK STDOUT: from core import BlogView, SinglePostView, SearchResultsView, ArchiveView HOOK STDOUT: HOOK STDOUT: urlpatterns = [ HOOK STDOUT: url('/blog', BlogView, name="blog"), HOOK STDOUT: url('/blog/:id', SinglePostView, name="singlepost"), HOOK STDOUT: url('/blog/search/:query', SearchResultsView, name="search"), HOOK STDOUT: url('/blog/archive/:date', ArchiveView, name="archive") HOOK STDOUT: ] HOOK STDOUT: ``` HOOK STDOUT: No regex, just clean paths and param names. You can now pass the regex work to DjUrl and concentrate in the *bussiness logic*. It saves you a lot of time and code. *You don't need to worry about the routes anymore*. **Note you don't need to call `as_view` in your CBV's.** DjUrl does this for you as well. HOOK STDOUT: HOOK STDOUT: Usage HOOK STDOUT: --- HOOK STDOUT: Now you know what you should use `DjUrl`, It's time to learn how to use it. DjUrl has a list of known/default pattern that you can use in your routes, these are: HOOK STDOUT: HOOK STDOUT: * `id`: A secuence of characters from 0 to 9. Ej: `1, 12, 454545, 8885500, 8` HOOK STDOUT: * `pk`: A primary key, it's like `id` but needed for `Class Based Views`. HOOK STDOUT: * `page`: falls in the same category, but you'd use `page` for a better param name. HOOK STDOUT: * `slug`: A simple string (alphanumeric characters). HOOK STDOUT: * `query`: A search parameter. It allows some special characters that *slug* doesn't. Ex: `hello%20word`, `don%27t_quote-me` HOOK STDOUT: * `day`: A number between 01,..., 31. HOOK STDOUT: * `month`: A number between 01,...,12. HOOK STDOUT: * `year`: A four digits number: `1998, 2017, 2018, 3015, 2020, 1406...` HOOK STDOUT: * `date`: An expression with `year-month-day` format: `2017-06-23, 1998-10-20, 1492-10-12` HOOK STDOUT: * `filename`: An expression with `*.\w{2,4}` format: `index.js`, `detail.html`, `'my_book.pdf'`, `'dfj358h-g9854-fn84n4.tmp'` HOOK STDOUT: * `UUID`: *Universally unique identifier* is a 128-bit number used to identify information in computer systems. Use a format as `xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx`. Ex: `123e4567-e89b-12d3-a456-426655440000` HOOK STDOUT: HOOK STDOUT: That means, wherever you put `/:id` you can use it in your view as param (named `id`). HOOK STDOUT: ```python HOOK STDOUT: url('post/:pk/comment/:id', myview, name="post_comment") HOOK STDOUT: ``` HOOK STDOUT: Your view: HOOK STDOUT: ```python HOOK STDOUT: def myview(request, pk, id): HOOK STDOUT: # Use `pk` (post's) and `id` (comment's) HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: But what if I have two or more id's, or two slugs? What if I wanted to use a custom name for my id's? - Ok, you can use custom names if you end it with `_` + the pattern type. - What?... HOOK STDOUT: ```python HOOK STDOUT: url('post/:post_pk/comment/:comment_id', myview, ...) HOOK STDOUT: # ... HOOK STDOUT: def myview(request, post_pk, comment_id): HOOK STDOUT: # `post_pk` is parsed as a :pk and `comment_id` like an :id HOOK STDOUT: HOOK STDOUT: ``` HOOK STDOUT: Yeah, it sounds good!, but... What if I wanted to use my own patterns? - Easy, any world in the path is of type `:slug` by default, but if you need a custom pattern you can register many as you want: HOOK STDOUT: ```python HOOK STDOUT: from djurl import url, register_pattern HOOK STDOUT: register_pattern('hash', '[a-f0-9]{9}') HOOK STDOUT: # parsed as slug HOOK STDOUT: url('/:user', myUserView), HOOK STDOUT: # custom pattern HOOK STDOUT: url('/:hash', myview), HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: If you have questions, visit our [FAQ's](FAQ.md) or open an *issue*. HOOK STDOUT: HOOK STDOUT: Install HOOK STDOUT: --- HOOK STDOUT: If you want to have fun with this library and integrate it to your project, just type in your terminal: HOOK STDOUT: ``` HOOK STDOUT: $ pip install djurl HOOK STDOUT: ``` HOOK STDOUT: or, clone the repo and type: HOOK STDOUT: ``` HOOK STDOUT: $ python setup.py install HOOK STDOUT: ``` HOOK STDOUT: Enjoy it! HOOK STDOUT: HOOK STDOUT: Testing HOOK STDOUT: --- HOOK STDOUT: Clone the repo and run Djurl tests by: HOOK STDOUT: ``` HOOK STDOUT: $ python setup.py test HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: Contributions HOOK STDOUT: --- HOOK STDOUT: If you've found a bug/error or just have questions, feel free to open an **issue**. And, **Pull requests** are welcome as well. HOOK STDOUT: Don't forget to add your name to [CONTRIBUTORS.md](CONTRIBUTORS.md) HOOK STDOUT: HOOK STDOUT: License HOOK STDOUT: ======= HOOK STDOUT: HOOK STDOUT: Copyright 2017 Christopher Ventura HOOK STDOUT: HOOK STDOUT: Licensed under the Apache License, Version 2.0 (the "License"); HOOK STDOUT: you may not use this file except in compliance with the License. HOOK STDOUT: You may obtain a copy of the License at HOOK STDOUT: HOOK STDOUT: http://www.apache.org/licenses/LICENSE-2.0 HOOK STDOUT: HOOK STDOUT: Unless required by applicable law or agreed to in writing, software HOOK STDOUT: distributed under the License is distributed on an "AS IS" BASIS, HOOK STDOUT: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. HOOK STDOUT: See the License for the specific language governing permissions and HOOK STDOUT: limitations under the License. HOOK STDOUT: Handling django from wheel metadata: Requires-Dist Requirement not satisfied: django + RPM_EC=0 ++ jobs -p + exit 0 Wrote: /builddir/build/SRPMS/python-djurl-0.2.0-1.fc37.buildreqs.nosrc.rpm Child return code was: 11 Dynamic buildrequires detected Going to install missing buildrequires. See root.log for details. ENTER ['do_with_status'](['bash', '--login', '-c', '/usr/bin/rpmbuild -br --target x86_64 --nodeps /builddir/build/SPECS/python-djurl.spec'], chrootPath='/var/lib/mock/fedora-rawhide-x86_64-1646296368.101088/root'env={'TERM': 'vt100', 'SHELL': '/bin/bash', 'HOME': '/builddir', 'HOSTNAME': 'mock', 'PATH': '/usr/bin:/bin:/usr/sbin:/sbin', 'PROMPT_COMMAND': 'printf "\\033]0;\\007"', 'PS1': ' \\s-\\v\\$ ', 'LANG': 'C.UTF-8'}shell=Falselogger=timeout=0uid=1000gid=135user='mockbuild'nspawn_args=['--capability=cap_ipc_lock', '--rlimit=RLIMIT_NOFILE=10240', '--capability=cap_ipc_lock', '--bind=/tmp/mock-resolv.46fwcqyf:/etc/resolv.conf', '--bind=/dev/btrfs-control', '--bind=/dev/loop-control', '--bind=/dev/loop0', '--bind=/dev/loop1', '--bind=/dev/loop2', '--bind=/dev/loop3', '--bind=/dev/loop4', '--bind=/dev/loop5', '--bind=/dev/loop6', '--bind=/dev/loop7', '--bind=/dev/loop8', '--bind=/dev/loop9', '--bind=/dev/loop10', '--bind=/dev/loop11']unshare_net=TrueraiseExc=FalseprintOutput=True) Using nspawn with args ['--capability=cap_ipc_lock', '--rlimit=RLIMIT_NOFILE=10240', '--capability=cap_ipc_lock', '--bind=/tmp/mock-resolv.46fwcqyf:/etc/resolv.conf', '--bind=/dev/btrfs-control', '--bind=/dev/loop-control', '--bind=/dev/loop0', '--bind=/dev/loop1', '--bind=/dev/loop2', '--bind=/dev/loop3', '--bind=/dev/loop4', '--bind=/dev/loop5', '--bind=/dev/loop6', '--bind=/dev/loop7', '--bind=/dev/loop8', '--bind=/dev/loop9', '--bind=/dev/loop10', '--bind=/dev/loop11'] Executing command: ['/usr/bin/systemd-nspawn', '-q', '-M', 'ce418e663c254ed8825e88a15f6854b3', '-D', '/var/lib/mock/fedora-rawhide-x86_64-1646296368.101088/root', '-a', '-u', 'mockbuild', '--capability=cap_ipc_lock', '--rlimit=RLIMIT_NOFILE=10240', '--capability=cap_ipc_lock', '--bind=/tmp/mock-resolv.46fwcqyf:/etc/resolv.conf', '--bind=/dev/btrfs-control', '--bind=/dev/loop-control', '--bind=/dev/loop0', '--bind=/dev/loop1', '--bind=/dev/loop2', '--bind=/dev/loop3', '--bind=/dev/loop4', '--bind=/dev/loop5', '--bind=/dev/loop6', '--bind=/dev/loop7', '--bind=/dev/loop8', '--bind=/dev/loop9', '--bind=/dev/loop10', '--bind=/dev/loop11', '--console=pipe', '--setenv=TERM=vt100', '--setenv=SHELL=/bin/bash', '--setenv=HOME=/builddir', '--setenv=HOSTNAME=mock', '--setenv=PATH=/usr/bin:/bin:/usr/sbin:/sbin', '--setenv=PROMPT_COMMAND=printf "\\033]0;\\007"', '--setenv=PS1= \\s-\\v\\$ ', '--setenv=LANG=C.UTF-8', '--resolv-conf=off', 'bash', '--login', '-c', '/usr/bin/rpmbuild -br --target x86_64 --nodeps /builddir/build/SPECS/python-djurl.spec'] with env {'TERM': 'vt100', 'SHELL': '/bin/bash', 'HOME': '/builddir', 'HOSTNAME': 'mock', 'PATH': '/usr/bin:/bin:/usr/sbin:/sbin', 'PROMPT_COMMAND': 'printf "\\033]0;\\007"', 'PS1': ' \\s-\\v\\$ ', 'LANG': 'C.UTF-8', 'SYSTEMD_NSPAWN_TMPFS_TMP': '0', 'SYSTEMD_SECCOMP': '0'} and shell False Building target platforms: x86_64 Building for target x86_64 setting SOURCE_DATE_EPOCH=1645920000 Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.Qhltke + umask 022 + cd /builddir/build/BUILD + cd /builddir/build/BUILD + rm -rf djurl-0.2.0 + /usr/bin/gzip -dc /builddir/build/SOURCES/djurl-0.2.0.tar.gz + /usr/bin/tar -xof - + STATUS=0 + '[' 0 -ne 0 ']' + cd djurl-0.2.0 + /usr/bin/chmod -Rf a+rX,u+w,g-w,o-w . + RPM_EC=0 ++ jobs -p + exit 0 Executing(%generate_buildrequires): /bin/sh -e /var/tmp/rpm-tmp.ajwSYA + umask 022 + cd /builddir/build/BUILD + cd djurl-0.2.0 + echo pyproject-rpm-macros + echo python3-devel + echo 'python3dist(pip) >= 19' + echo 'python3dist(packaging)' + '[' -f pyproject.toml ']' + '[' -f setup.py ']' + echo 'python3dist(setuptools) >= 40.8' + echo 'python3dist(wheel)' + rm -rfv '*.dist-info/' + '[' -f /usr/bin/python3 ']' + RPM_TOXENV=py310 + HOSTNAME=rpmbuild + /usr/bin/python3 -s /usr/lib/rpm/redhat/pyproject_buildrequires.py --generate-extras --python3_pkgversion 3 -r Handling setuptools >= 40.8 from default build backend Requirement satisfied: setuptools >= 40.8 (installed: setuptools 59.6.0) Handling wheel from default build backend Requirement satisfied: wheel (installed: wheel 0.37.0) /usr/lib/python3.10/site-packages/setuptools/dist.py:723: UserWarning: Usage of dash-separated 'description-file' will not be supported in future versions. Please use the underscore name 'description_file' instead warnings.warn( HOOK STDOUT: running egg_info HOOK STDOUT: writing djurl.egg-info/PKG-INFO HOOK STDOUT: writing dependency_links to djurl.egg-info/dependency_links.txt HOOK STDOUT: writing requirements to djurl.egg-info/requires.txt HOOK STDOUT: writing top-level names to djurl.egg-info/top_level.txt HOOK STDOUT: reading manifest file 'djurl.egg-info/SOURCES.txt' HOOK STDOUT: reading manifest template 'MANIFEST.in' HOOK STDOUT: writing manifest file 'djurl.egg-info/SOURCES.txt' HOOK STDOUT: ![DjUrl - Django urls](/djurlheader.png) [![Build Status](https://travis-ci.org/venturachrisdev/djurl.svg?branch=master)](https://travis-ci.org/venturachrisdev/djurl) HOOK STDOUT: === HOOK STDOUT: Simple yet helpful library for writing Django urls by an easy, short an intuitive way. HOOK STDOUT: HOOK STDOUT: Why should I use DjUrl? HOOK STDOUT: --- HOOK STDOUT: Django routing urls aren't easy to deal with, regular expressions can become a nightmare sometimes. Just imagine dealing with such routes in your `django app`: HOOK STDOUT: ```python HOOK STDOUT: from django.conf.urls import url HOOK STDOUT: from core import BlogView, SinglePostView, SearchResultsView, ArchiveView HOOK STDOUT: HOOK STDOUT: urlpatterns = [ HOOK STDOUT: # => /blog/ HOOK STDOUT: url(r'^blog/$', BlogView.as_view(), name="blog"), HOOK STDOUT: # => /blog/5 HOOK STDOUT: url(r'^blog/(?P[0-9]+)/$', SinglePostView.as_view(), name="singlepost"), HOOK STDOUT: # => /blog/search/sometitle HOOK STDOUT: url(r'^blog/search/(?P[A-Za-z0-9_-]+)/$', SearchResultsView.as_view(), name="search"), HOOK STDOUT: # => /blog/archive/2017/02/12 HOOK STDOUT: url(r'^blog/archive/(?P[0-9]{4}-(0?([1-9])|10|11|12)-((0|1|2)?([1-9])|[1-3]0|31))/$', HOOK STDOUT: ArchiveView.as_view(), name="archive") HOOK STDOUT: ] HOOK STDOUT: ``` HOOK STDOUT: That's too much work and you lost me in those regex. With **DjUrl** this comes easy, you just need to *express what you want*, **DjUrl will handle the regular expressions for you**: HOOK STDOUT: HOOK STDOUT: ```python HOOK STDOUT: from djurl import url HOOK STDOUT: from core import BlogView, SinglePostView, SearchResultsView, ArchiveView HOOK STDOUT: HOOK STDOUT: urlpatterns = [ HOOK STDOUT: url('/blog', BlogView, name="blog"), HOOK STDOUT: url('/blog/:id', SinglePostView, name="singlepost"), HOOK STDOUT: url('/blog/search/:query', SearchResultsView, name="search"), HOOK STDOUT: url('/blog/archive/:date', ArchiveView, name="archive") HOOK STDOUT: ] HOOK STDOUT: ``` HOOK STDOUT: No regex, just clean paths and param names. You can now pass the regex work to DjUrl and concentrate in the *bussiness logic*. It saves you a lot of time and code. *You don't need to worry about the routes anymore*. **Note you don't need to call `as_view` in your CBV's.** DjUrl does this for you as well. HOOK STDOUT: HOOK STDOUT: Usage HOOK STDOUT: --- HOOK STDOUT: Now you know what you should use `DjUrl`, It's time to learn how to use it. DjUrl has a list of known/default pattern that you can use in your routes, these are: HOOK STDOUT: HOOK STDOUT: * `id`: A secuence of characters from 0 to 9. Ej: `1, 12, 454545, 8885500, 8` HOOK STDOUT: * `pk`: A primary key, it's like `id` but needed for `Class Based Views`. HOOK STDOUT: * `page`: falls in the same category, but you'd use `page` for a better param name. HOOK STDOUT: * `slug`: A simple string (alphanumeric characters). HOOK STDOUT: * `query`: A search parameter. It allows some special characters that *slug* doesn't. Ex: `hello%20word`, `don%27t_quote-me` HOOK STDOUT: * `day`: A number between 01,..., 31. HOOK STDOUT: * `month`: A number between 01,...,12. HOOK STDOUT: * `year`: A four digits number: `1998, 2017, 2018, 3015, 2020, 1406...` HOOK STDOUT: * `date`: An expression with `year-month-day` format: `2017-06-23, 1998-10-20, 1492-10-12` HOOK STDOUT: * `filename`: An expression with `*.\w{2,4}` format: `index.js`, `detail.html`, `'my_book.pdf'`, `'dfj358h-g9854-fn84n4.tmp'` HOOK STDOUT: * `UUID`: *Universally unique identifier* is a 128-bit number used to identify information in computer systems. Use a format as `xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx`. Ex: `123e4567-e89b-12d3-a456-426655440000` HOOK STDOUT: HOOK STDOUT: That means, wherever you put `/:id` you can use it in your view as param (named `id`). HOOK STDOUT: ```python HOOK STDOUT: url('post/:pk/comment/:id', myview, name="post_comment") HOOK STDOUT: ``` HOOK STDOUT: Your view: HOOK STDOUT: ```python HOOK STDOUT: def myview(request, pk, id): HOOK STDOUT: # Use `pk` (post's) and `id` (comment's) HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: But what if I have two or more id's, or two slugs? What if I wanted to use a custom name for my id's? - Ok, you can use custom names if you end it with `_` + the pattern type. - What?... HOOK STDOUT: ```python HOOK STDOUT: url('post/:post_pk/comment/:comment_id', myview, ...) HOOK STDOUT: # ... HOOK STDOUT: def myview(request, post_pk, comment_id): HOOK STDOUT: # `post_pk` is parsed as a :pk and `comment_id` like an :id HOOK STDOUT: HOOK STDOUT: ``` HOOK STDOUT: Yeah, it sounds good!, but... What if I wanted to use my own patterns? - Easy, any world in the path is of type `:slug` by default, but if you need a custom pattern you can register many as you want: HOOK STDOUT: ```python HOOK STDOUT: from djurl import url, register_pattern HOOK STDOUT: register_pattern('hash', '[a-f0-9]{9}') HOOK STDOUT: # parsed as slug HOOK STDOUT: url('/:user', myUserView), HOOK STDOUT: # custom pattern HOOK STDOUT: url('/:hash', myview), HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: If you have questions, visit our [FAQ's](FAQ.md) or open an *issue*. HOOK STDOUT: HOOK STDOUT: Install HOOK STDOUT: --- HOOK STDOUT: If you want to have fun with this library and integrate it to your project, just type in your terminal: HOOK STDOUT: ``` HOOK STDOUT: $ pip install djurl HOOK STDOUT: ``` HOOK STDOUT: or, clone the repo and type: HOOK STDOUT: ``` HOOK STDOUT: $ python setup.py install HOOK STDOUT: ``` HOOK STDOUT: Enjoy it! HOOK STDOUT: HOOK STDOUT: Testing HOOK STDOUT: --- HOOK STDOUT: Clone the repo and run Djurl tests by: HOOK STDOUT: ``` HOOK STDOUT: $ python setup.py test HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: Contributions HOOK STDOUT: --- HOOK STDOUT: If you've found a bug/error or just have questions, feel free to open an **issue**. And, **Pull requests** are welcome as well. HOOK STDOUT: Don't forget to add your name to [CONTRIBUTORS.md](CONTRIBUTORS.md) HOOK STDOUT: HOOK STDOUT: License HOOK STDOUT: ======= HOOK STDOUT: HOOK STDOUT: Copyright 2017 Christopher Ventura HOOK STDOUT: HOOK STDOUT: Licensed under the Apache License, Version 2.0 (the "License"); HOOK STDOUT: you may not use this file except in compliance with the License. HOOK STDOUT: You may obtain a copy of the License at HOOK STDOUT: HOOK STDOUT: http://www.apache.org/licenses/LICENSE-2.0 HOOK STDOUT: HOOK STDOUT: Unless required by applicable law or agreed to in writing, software HOOK STDOUT: distributed under the License is distributed on an "AS IS" BASIS, HOOK STDOUT: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. HOOK STDOUT: See the License for the specific language governing permissions and HOOK STDOUT: limitations under the License. HOOK STDOUT: Handling wheel from get_requires_for_build_wheel Requirement satisfied: wheel (installed: wheel 0.37.0) HOOK STDOUT: running dist_info HOOK STDOUT: writing djurl.egg-info/PKG-INFO HOOK STDOUT: writing dependency_links to djurl.egg-info/dependency_links.txt HOOK STDOUT: writing requirements to djurl.egg-info/requires.txt HOOK STDOUT: writing top-level names to djurl.egg-info/top_level.txt HOOK STDOUT: reading manifest file 'djurl.egg-info/SOURCES.txt' HOOK STDOUT: reading manifest template 'MANIFEST.in' HOOK STDOUT: writing manifest file 'djurl.egg-info/SOURCES.txt' HOOK STDOUT: creating '/builddir/build/BUILD/djurl-0.2.0/djurl.dist-info' HOOK STDOUT: ![DjUrl - Django urls](/djurlheader.png) [![Build Status](https://travis-ci.org/venturachrisdev/djurl.svg?branch=master)](https://travis-ci.org/venturachrisdev/djurl) HOOK STDOUT: === HOOK STDOUT: Simple yet helpful library for writing Django urls by an easy, short an intuitive way. HOOK STDOUT: HOOK STDOUT: Why should I use DjUrl? HOOK STDOUT: --- HOOK STDOUT: Django routing urls aren't easy to deal with, regular expressions can become a nightmare sometimes. Just imagine dealing with such routes in your `django app`: HOOK STDOUT: ```python HOOK STDOUT: from django.conf.urls import url HOOK STDOUT: from core import BlogView, SinglePostView, SearchResultsView, ArchiveView HOOK STDOUT: HOOK STDOUT: urlpatterns = [ HOOK STDOUT: # => /blog/ HOOK STDOUT: url(r'^blog/$', BlogView.as_view(), name="blog"), HOOK STDOUT: # => /blog/5 HOOK STDOUT: url(r'^blog/(?P[0-9]+)/$', SinglePostView.as_view(), name="singlepost"), HOOK STDOUT: # => /blog/search/sometitle HOOK STDOUT: url(r'^blog/search/(?P[A-Za-z0-9_-]+)/$', SearchResultsView.as_view(), name="search"), HOOK STDOUT: # => /blog/archive/2017/02/12 HOOK STDOUT: url(r'^blog/archive/(?P[0-9]{4}-(0?([1-9])|10|11|12)-((0|1|2)?([1-9])|[1-3]0|31))/$', HOOK STDOUT: ArchiveView.as_view(), name="archive") HOOK STDOUT: ] HOOK STDOUT: ``` HOOK STDOUT: That's too much work and you lost me in those regex. With **DjUrl** this comes easy, you just need to *express what you want*, **DjUrl will handle the regular expressions for you**: HOOK STDOUT: HOOK STDOUT: ```python HOOK STDOUT: from djurl import url HOOK STDOUT: from core import BlogView, SinglePostView, SearchResultsView, ArchiveView HOOK STDOUT: HOOK STDOUT: urlpatterns = [ HOOK STDOUT: url('/blog', BlogView, name="blog"), HOOK STDOUT: url('/blog/:id', SinglePostView, name="singlepost"), HOOK STDOUT: url('/blog/search/:query', SearchResultsView, name="search"), HOOK STDOUT: url('/blog/archive/:date', ArchiveView, name="archive") HOOK STDOUT: ] HOOK STDOUT: ``` HOOK STDOUT: No regex, just clean paths and param names. You can now pass the regex work to DjUrl and concentrate in the *bussiness logic*. It saves you a lot of time and code. *You don't need to worry about the routes anymore*. **Note you don't need to call `as_view` in your CBV's.** DjUrl does this for you as well. HOOK STDOUT: HOOK STDOUT: Usage HOOK STDOUT: --- HOOK STDOUT: Now you know what you should use `DjUrl`, It's time to learn how to use it. DjUrl has a list of known/default pattern that you can use in your routes, these are: HOOK STDOUT: HOOK STDOUT: * `id`: A secuence of characters from 0 to 9. Ej: `1, 12, 454545, 8885500, 8` HOOK STDOUT: * `pk`: A primary key, it's like `id` but needed for `Class Based Views`. HOOK STDOUT: * `page`: falls in the same category, but you'd use `page` for a better param name. HOOK STDOUT: * `slug`: A simple string (alphanumeric characters). HOOK STDOUT: * `query`: A search parameter. It allows some special characters that *slug* doesn't. Ex: `hello%20word`, `don%27t_quote-me` HOOK STDOUT: * `day`: A number between 01,..., 31. HOOK STDOUT: * `month`: A number between 01,...,12. HOOK STDOUT: * `year`: A four digits number: `1998, 2017, 2018, 3015, 2020, 1406...` HOOK STDOUT: * `date`: An expression with `year-month-day` format: `2017-06-23, 1998-10-20, 1492-10-12` HOOK STDOUT: * `filename`: An expression with `*.\w{2,4}` format: `index.js`, `detail.html`, `'my_book.pdf'`, `'dfj358h-g9854-fn84n4.tmp'` HOOK STDOUT: * `UUID`: *Universally unique identifier* is a 128-bit number used to identify information in computer systems. Use a format as `xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx`. Ex: `123e4567-e89b-12d3-a456-426655440000` HOOK STDOUT: HOOK STDOUT: That means, wherever you put `/:id` you can use it in your view as param (named `id`). HOOK STDOUT: ```python HOOK STDOUT: url('post/:pk/comment/:id', myview, name="post_comment") HOOK STDOUT: ``` HOOK STDOUT: Your view: HOOK STDOUT: ```python HOOK STDOUT: def myview(request, pk, id): HOOK STDOUT: # Use `pk` (post's) and `id` (comment's) HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: But what if I have two or more id's, or two slugs? What if I wanted to use a custom name for my id's? - Ok, you can use custom names if you end it with `_` + the pattern type. - What?... HOOK STDOUT: ```python HOOK STDOUT: url('post/:post_pk/comment/:comment_id', myview, ...) HOOK STDOUT: # ... HOOK STDOUT: def myview(request, post_pk, comment_id): HOOK STDOUT: # `post_pk` is parsed as a :pk and `comment_id` like an :id HOOK STDOUT: HOOK STDOUT: ``` HOOK STDOUT: Yeah, it sounds good!, but... What if I wanted to use my own patterns? - Easy, any world in the path is of type `:slug` by default, but if you need a custom pattern you can register many as you want: HOOK STDOUT: ```python HOOK STDOUT: from djurl import url, register_pattern HOOK STDOUT: register_pattern('hash', '[a-f0-9]{9}') HOOK STDOUT: # parsed as slug HOOK STDOUT: url('/:user', myUserView), HOOK STDOUT: # custom pattern HOOK STDOUT: url('/:hash', myview), HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: If you have questions, visit our [FAQ's](FAQ.md) or open an *issue*. HOOK STDOUT: HOOK STDOUT: Install HOOK STDOUT: --- HOOK STDOUT: If you want to have fun with this library and integrate it to your project, just type in your terminal: HOOK STDOUT: ``` HOOK STDOUT: $ pip install djurl HOOK STDOUT: ``` HOOK STDOUT: or, clone the repo and type: HOOK STDOUT: ``` HOOK STDOUT: $ python setup.py install HOOK STDOUT: ``` HOOK STDOUT: Enjoy it! HOOK STDOUT: HOOK STDOUT: Testing HOOK STDOUT: --- HOOK STDOUT: Clone the repo and run Djurl tests by: HOOK STDOUT: ``` HOOK STDOUT: $ python setup.py test HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: Contributions HOOK STDOUT: --- HOOK STDOUT: If you've found a bug/error or just have questions, feel free to open an **issue**. And, **Pull requests** are welcome as well. HOOK STDOUT: Don't forget to add your name to [CONTRIBUTORS.md](CONTRIBUTORS.md) HOOK STDOUT: HOOK STDOUT: License HOOK STDOUT: ======= HOOK STDOUT: HOOK STDOUT: Copyright 2017 Christopher Ventura HOOK STDOUT: HOOK STDOUT: Licensed under the Apache License, Version 2.0 (the "License"); HOOK STDOUT: you may not use this file except in compliance with the License. HOOK STDOUT: You may obtain a copy of the License at HOOK STDOUT: HOOK STDOUT: http://www.apache.org/licenses/LICENSE-2.0 HOOK STDOUT: HOOK STDOUT: Unless required by applicable law or agreed to in writing, software HOOK STDOUT: distributed under the License is distributed on an "AS IS" BASIS, HOOK STDOUT: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. HOOK STDOUT: See the License for the specific language governing permissions and HOOK STDOUT: limitations under the License. HOOK STDOUT: Handling django from wheel metadata: Requires-Dist Requirement satisfied: django (installed: django 4.0.2) + RPM_EC=0 ++ jobs -p + exit 0 Wrote: /builddir/build/SRPMS/python-djurl-0.2.0-1.fc37.buildreqs.nosrc.rpm Child return code was: 11 Dynamic buildrequires detected Going to install missing buildrequires. See root.log for details. ENTER ['do_with_status'](['bash', '--login', '-c', '/usr/bin/rpmbuild -ba --noprep --target x86_64 --nodeps /builddir/build/SPECS/python-djurl.spec'], chrootPath='/var/lib/mock/fedora-rawhide-x86_64-1646296368.101088/root'env={'TERM': 'vt100', 'SHELL': '/bin/bash', 'HOME': '/builddir', 'HOSTNAME': 'mock', 'PATH': '/usr/bin:/bin:/usr/sbin:/sbin', 'PROMPT_COMMAND': 'printf "\\033]0;\\007"', 'PS1': ' \\s-\\v\\$ ', 'LANG': 'C.UTF-8'}shell=Falselogger=timeout=0uid=1000gid=135user='mockbuild'nspawn_args=['--capability=cap_ipc_lock', '--rlimit=RLIMIT_NOFILE=10240', '--capability=cap_ipc_lock', '--bind=/tmp/mock-resolv.46fwcqyf:/etc/resolv.conf', '--bind=/dev/btrfs-control', '--bind=/dev/loop-control', '--bind=/dev/loop0', '--bind=/dev/loop1', '--bind=/dev/loop2', '--bind=/dev/loop3', '--bind=/dev/loop4', '--bind=/dev/loop5', '--bind=/dev/loop6', '--bind=/dev/loop7', '--bind=/dev/loop8', '--bind=/dev/loop9', '--bind=/dev/loop10', '--bind=/dev/loop11']unshare_net=TrueprintOutput=True) Using nspawn with args ['--capability=cap_ipc_lock', '--rlimit=RLIMIT_NOFILE=10240', '--capability=cap_ipc_lock', '--bind=/tmp/mock-resolv.46fwcqyf:/etc/resolv.conf', '--bind=/dev/btrfs-control', '--bind=/dev/loop-control', '--bind=/dev/loop0', '--bind=/dev/loop1', '--bind=/dev/loop2', '--bind=/dev/loop3', '--bind=/dev/loop4', '--bind=/dev/loop5', '--bind=/dev/loop6', '--bind=/dev/loop7', '--bind=/dev/loop8', '--bind=/dev/loop9', '--bind=/dev/loop10', '--bind=/dev/loop11'] Executing command: ['/usr/bin/systemd-nspawn', '-q', '-M', 'f0431aab90554ee8a4855cb0eb8f320f', '-D', '/var/lib/mock/fedora-rawhide-x86_64-1646296368.101088/root', '-a', '-u', 'mockbuild', '--capability=cap_ipc_lock', '--rlimit=RLIMIT_NOFILE=10240', '--capability=cap_ipc_lock', '--bind=/tmp/mock-resolv.46fwcqyf:/etc/resolv.conf', '--bind=/dev/btrfs-control', '--bind=/dev/loop-control', '--bind=/dev/loop0', '--bind=/dev/loop1', '--bind=/dev/loop2', '--bind=/dev/loop3', '--bind=/dev/loop4', '--bind=/dev/loop5', '--bind=/dev/loop6', '--bind=/dev/loop7', '--bind=/dev/loop8', '--bind=/dev/loop9', '--bind=/dev/loop10', '--bind=/dev/loop11', '--console=pipe', '--setenv=TERM=vt100', '--setenv=SHELL=/bin/bash', '--setenv=HOME=/builddir', '--setenv=HOSTNAME=mock', '--setenv=PATH=/usr/bin:/bin:/usr/sbin:/sbin', '--setenv=PROMPT_COMMAND=printf "\\033]0;\\007"', '--setenv=PS1= \\s-\\v\\$ ', '--setenv=LANG=C.UTF-8', '--resolv-conf=off', 'bash', '--login', '-c', '/usr/bin/rpmbuild -ba --noprep --target x86_64 --nodeps /builddir/build/SPECS/python-djurl.spec'] with env {'TERM': 'vt100', 'SHELL': '/bin/bash', 'HOME': '/builddir', 'HOSTNAME': 'mock', 'PATH': '/usr/bin:/bin:/usr/sbin:/sbin', 'PROMPT_COMMAND': 'printf "\\033]0;\\007"', 'PS1': ' \\s-\\v\\$ ', 'LANG': 'C.UTF-8', 'SYSTEMD_NSPAWN_TMPFS_TMP': '0', 'SYSTEMD_SECCOMP': '0'} and shell False Building target platforms: x86_64 Building for target x86_64 setting SOURCE_DATE_EPOCH=1645920000 Executing(%generate_buildrequires): /bin/sh -e /var/tmp/rpm-tmp.wu6PDl + umask 022 + cd /builddir/build/BUILD + cd djurl-0.2.0 + echo pyproject-rpm-macros + echo python3-devel + echo 'python3dist(pip) >= 19' + echo 'python3dist(packaging)' + '[' -f pyproject.toml ']' + '[' -f setup.py ']' + echo 'python3dist(setuptools) >= 40.8' + echo 'python3dist(wheel)' + rm -rfv djurl.dist-info/ removed 'djurl.dist-info/METADATA' removed 'djurl.dist-info/top_level.txt' removed directory 'djurl.dist-info/' + '[' -f /usr/bin/python3 ']' + RPM_TOXENV=py310 + HOSTNAME=rpmbuild + /usr/bin/python3 -s /usr/lib/rpm/redhat/pyproject_buildrequires.py --generate-extras --python3_pkgversion 3 -r Handling setuptools >= 40.8 from default build backend Requirement satisfied: setuptools >= 40.8 (installed: setuptools 59.6.0) Handling wheel from default build backend Requirement satisfied: wheel (installed: wheel 0.37.0) /usr/lib/python3.10/site-packages/setuptools/dist.py:723: UserWarning: Usage of dash-separated 'description-file' will not be supported in future versions. Please use the underscore name 'description_file' instead warnings.warn( HOOK STDOUT: running egg_info HOOK STDOUT: creating djurl.egg-info HOOK STDOUT: writing djurl.egg-info/PKG-INFO HOOK STDOUT: writing dependency_links to djurl.egg-info/dependency_links.txt HOOK STDOUT: writing requirements to djurl.egg-info/requires.txt HOOK STDOUT: writing top-level names to djurl.egg-info/top_level.txt HOOK STDOUT: writing manifest file 'djurl.egg-info/SOURCES.txt' HOOK STDOUT: reading manifest file 'djurl.egg-info/SOURCES.txt' HOOK STDOUT: reading manifest template 'MANIFEST.in' HOOK STDOUT: writing manifest file 'djurl.egg-info/SOURCES.txt' HOOK STDOUT: ![DjUrl - Django urls](/djurlheader.png) [![Build Status](https://travis-ci.org/venturachrisdev/djurl.svg?branch=master)](https://travis-ci.org/venturachrisdev/djurl) HOOK STDOUT: === HOOK STDOUT: Simple yet helpful library for writing Django urls by an easy, short an intuitive way. HOOK STDOUT: HOOK STDOUT: Why should I use DjUrl? HOOK STDOUT: --- HOOK STDOUT: Django routing urls aren't easy to deal with, regular expressions can become a nightmare sometimes. Just imagine dealing with such routes in your `django app`: HOOK STDOUT: ```python HOOK STDOUT: from django.conf.urls import url HOOK STDOUT: from core import BlogView, SinglePostView, SearchResultsView, ArchiveView HOOK STDOUT: HOOK STDOUT: urlpatterns = [ HOOK STDOUT: # => /blog/ HOOK STDOUT: url(r'^blog/$', BlogView.as_view(), name="blog"), HOOK STDOUT: # => /blog/5 HOOK STDOUT: url(r'^blog/(?P[0-9]+)/$', SinglePostView.as_view(), name="singlepost"), HOOK STDOUT: # => /blog/search/sometitle HOOK STDOUT: url(r'^blog/search/(?P[A-Za-z0-9_-]+)/$', SearchResultsView.as_view(), name="search"), HOOK STDOUT: # => /blog/archive/2017/02/12 HOOK STDOUT: url(r'^blog/archive/(?P[0-9]{4}-(0?([1-9])|10|11|12)-((0|1|2)?([1-9])|[1-3]0|31))/$', HOOK STDOUT: ArchiveView.as_view(), name="archive") HOOK STDOUT: ] HOOK STDOUT: ``` HOOK STDOUT: That's too much work and you lost me in those regex. With **DjUrl** this comes easy, you just need to *express what you want*, **DjUrl will handle the regular expressions for you**: HOOK STDOUT: HOOK STDOUT: ```python HOOK STDOUT: from djurl import url HOOK STDOUT: from core import BlogView, SinglePostView, SearchResultsView, ArchiveView HOOK STDOUT: HOOK STDOUT: urlpatterns = [ HOOK STDOUT: url('/blog', BlogView, name="blog"), HOOK STDOUT: url('/blog/:id', SinglePostView, name="singlepost"), HOOK STDOUT: url('/blog/search/:query', SearchResultsView, name="search"), HOOK STDOUT: url('/blog/archive/:date', ArchiveView, name="archive") HOOK STDOUT: ] HOOK STDOUT: ``` HOOK STDOUT: No regex, just clean paths and param names. You can now pass the regex work to DjUrl and concentrate in the *bussiness logic*. It saves you a lot of time and code. *You don't need to worry about the routes anymore*. **Note you don't need to call `as_view` in your CBV's.** DjUrl does this for you as well. HOOK STDOUT: HOOK STDOUT: Usage HOOK STDOUT: --- HOOK STDOUT: Now you know what you should use `DjUrl`, It's time to learn how to use it. DjUrl has a list of known/default pattern that you can use in your routes, these are: HOOK STDOUT: HOOK STDOUT: * `id`: A secuence of characters from 0 to 9. Ej: `1, 12, 454545, 8885500, 8` HOOK STDOUT: * `pk`: A primary key, it's like `id` but needed for `Class Based Views`. HOOK STDOUT: * `page`: falls in the same category, but you'd use `page` for a better param name. HOOK STDOUT: * `slug`: A simple string (alphanumeric characters). HOOK STDOUT: * `query`: A search parameter. It allows some special characters that *slug* doesn't. Ex: `hello%20word`, `don%27t_quote-me` HOOK STDOUT: * `day`: A number between 01,..., 31. HOOK STDOUT: * `month`: A number between 01,...,12. HOOK STDOUT: * `year`: A four digits number: `1998, 2017, 2018, 3015, 2020, 1406...` HOOK STDOUT: * `date`: An expression with `year-month-day` format: `2017-06-23, 1998-10-20, 1492-10-12` HOOK STDOUT: * `filename`: An expression with `*.\w{2,4}` format: `index.js`, `detail.html`, `'my_book.pdf'`, `'dfj358h-g9854-fn84n4.tmp'` HOOK STDOUT: * `UUID`: *Universally unique identifier* is a 128-bit number used to identify information in computer systems. Use a format as `xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx`. Ex: `123e4567-e89b-12d3-a456-426655440000` HOOK STDOUT: HOOK STDOUT: That means, wherever you put `/:id` you can use it in your view as param (named `id`). HOOK STDOUT: ```python HOOK STDOUT: url('post/:pk/comment/:id', myview, name="post_comment") HOOK STDOUT: ``` HOOK STDOUT: Your view: HOOK STDOUT: ```python HOOK STDOUT: def myview(request, pk, id): HOOK STDOUT: # Use `pk` (post's) and `id` (comment's) HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: But what if I have two or more id's, or two slugs? What if I wanted to use a custom name for my id's? - Ok, you can use custom names if you end it with `_` + the pattern type. - What?... HOOK STDOUT: ```python HOOK STDOUT: url('post/:post_pk/comment/:comment_id', myview, ...) HOOK STDOUT: # ... HOOK STDOUT: def myview(request, post_pk, comment_id): HOOK STDOUT: # `post_pk` is parsed as a :pk and `comment_id` like an :id HOOK STDOUT: HOOK STDOUT: ``` HOOK STDOUT: Yeah, it sounds good!, but... What if I wanted to use my own patterns? - Easy, any world in the path is of type `:slug` by default, but if you need a custom pattern you can register many as you want: HOOK STDOUT: ```python HOOK STDOUT: from djurl import url, register_pattern HOOK STDOUT: register_pattern('hash', '[a-f0-9]{9}') HOOK STDOUT: # parsed as slug HOOK STDOUT: url('/:user', myUserView), HOOK STDOUT: # custom pattern HOOK STDOUT: url('/:hash', myview), HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: If you have questions, visit our [FAQ's](FAQ.md) or open an *issue*. HOOK STDOUT: HOOK STDOUT: Install HOOK STDOUT: --- HOOK STDOUT: If you want to have fun with this library and integrate it to your project, just type in your terminal: HOOK STDOUT: ``` HOOK STDOUT: $ pip install djurl HOOK STDOUT: ``` HOOK STDOUT: or, clone the repo and type: HOOK STDOUT: ``` HOOK STDOUT: $ python setup.py install HOOK STDOUT: ``` HOOK STDOUT: Enjoy it! HOOK STDOUT: HOOK STDOUT: Testing HOOK STDOUT: --- HOOK STDOUT: Clone the repo and run Djurl tests by: HOOK STDOUT: ``` HOOK STDOUT: $ python setup.py test HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: Contributions HOOK STDOUT: --- HOOK STDOUT: If you've found a bug/error or just have questions, feel free to open an **issue**. And, **Pull requests** are welcome as well. HOOK STDOUT: Don't forget to add your name to [CONTRIBUTORS.md](CONTRIBUTORS.md) HOOK STDOUT: HOOK STDOUT: License HOOK STDOUT: ======= HOOK STDOUT: HOOK STDOUT: Copyright 2017 Christopher Ventura HOOK STDOUT: HOOK STDOUT: Licensed under the Apache License, Version 2.0 (the "License"); HOOK STDOUT: you may not use this file except in compliance with the License. HOOK STDOUT: You may obtain a copy of the License at HOOK STDOUT: HOOK STDOUT: http://www.apache.org/licenses/LICENSE-2.0 HOOK STDOUT: HOOK STDOUT: Unless required by applicable law or agreed to in writing, software HOOK STDOUT: distributed under the License is distributed on an "AS IS" BASIS, HOOK STDOUT: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. HOOK STDOUT: See the License for the specific language governing permissions and HOOK STDOUT: limitations under the License. HOOK STDOUT: Handling wheel from get_requires_for_build_wheel Requirement satisfied: wheel (installed: wheel 0.37.0) HOOK STDOUT: running dist_info HOOK STDOUT: writing djurl.egg-info/PKG-INFO HOOK STDOUT: writing dependency_links to djurl.egg-info/dependency_links.txt HOOK STDOUT: writing requirements to djurl.egg-info/requires.txt HOOK STDOUT: writing top-level names to djurl.egg-info/top_level.txt HOOK STDOUT: reading manifest file 'djurl.egg-info/SOURCES.txt' HOOK STDOUT: reading manifest template 'MANIFEST.in' HOOK STDOUT: writing manifest file 'djurl.egg-info/SOURCES.txt' HOOK STDOUT: creating '/builddir/build/BUILD/djurl-0.2.0/djurl.dist-info' HOOK STDOUT: ![DjUrl - Django urls](/djurlheader.png) [![Build Status](https://travis-ci.org/venturachrisdev/djurl.svg?branch=master)](https://travis-ci.org/venturachrisdev/djurl) HOOK STDOUT: === HOOK STDOUT: Simple yet helpful library for writing Django urls by an easy, short an intuitive way. HOOK STDOUT: HOOK STDOUT: Why should I use DjUrl? HOOK STDOUT: --- HOOK STDOUT: Django routing urls aren't easy to deal with, regular expressions can become a nightmare sometimes. Just imagine dealing with such routes in your `django app`: HOOK STDOUT: ```python HOOK STDOUT: from django.conf.urls import url HOOK STDOUT: from core import BlogView, SinglePostView, SearchResultsView, ArchiveView HOOK STDOUT: HOOK STDOUT: urlpatterns = [ HOOK STDOUT: # => /blog/ HOOK STDOUT: url(r'^blog/$', BlogView.as_view(), name="blog"), HOOK STDOUT: # => /blog/5 HOOK STDOUT: url(r'^blog/(?P[0-9]+)/$', SinglePostView.as_view(), name="singlepost"), HOOK STDOUT: # => /blog/search/sometitle HOOK STDOUT: url(r'^blog/search/(?P[A-Za-z0-9_-]+)/$', SearchResultsView.as_view(), name="search"), HOOK STDOUT: # => /blog/archive/2017/02/12 HOOK STDOUT: url(r'^blog/archive/(?P[0-9]{4}-(0?([1-9])|10|11|12)-((0|1|2)?([1-9])|[1-3]0|31))/$', HOOK STDOUT: ArchiveView.as_view(), name="archive") HOOK STDOUT: ] HOOK STDOUT: ``` HOOK STDOUT: That's too much work and you lost me in those regex. With **DjUrl** this comes easy, you just need to *express what you want*, **DjUrl will handle the regular expressions for you**: HOOK STDOUT: HOOK STDOUT: ```python HOOK STDOUT: from djurl import url HOOK STDOUT: from core import BlogView, SinglePostView, SearchResultsView, ArchiveView HOOK STDOUT: HOOK STDOUT: urlpatterns = [ HOOK STDOUT: url('/blog', BlogView, name="blog"), HOOK STDOUT: url('/blog/:id', SinglePostView, name="singlepost"), HOOK STDOUT: url('/blog/search/:query', SearchResultsView, name="search"), HOOK STDOUT: url('/blog/archive/:date', ArchiveView, name="archive") HOOK STDOUT: ] HOOK STDOUT: ``` HOOK STDOUT: No regex, just clean paths and param names. You can now pass the regex work to DjUrl and concentrate in the *bussiness logic*. It saves you a lot of time and code. *You don't need to worry about the routes anymore*. **Note you don't need to call `as_view` in your CBV's.** DjUrl does this for you as well. HOOK STDOUT: HOOK STDOUT: Usage HOOK STDOUT: --- HOOK STDOUT: Now you know what you should use `DjUrl`, It's time to learn how to use it. DjUrl has a list of known/default pattern that you can use in your routes, these are: HOOK STDOUT: HOOK STDOUT: * `id`: A secuence of characters from 0 to 9. Ej: `1, 12, 454545, 8885500, 8` HOOK STDOUT: * `pk`: A primary key, it's like `id` but needed for `Class Based Views`. HOOK STDOUT: * `page`: falls in the same category, but you'd use `page` for a better param name. HOOK STDOUT: * `slug`: A simple string (alphanumeric characters). HOOK STDOUT: * `query`: A search parameter. It allows some special characters that *slug* doesn't. Ex: `hello%20word`, `don%27t_quote-me` HOOK STDOUT: * `day`: A number between 01,..., 31. HOOK STDOUT: * `month`: A number between 01,...,12. HOOK STDOUT: * `year`: A four digits number: `1998, 2017, 2018, 3015, 2020, 1406...` HOOK STDOUT: * `date`: An expression with `year-month-day` format: `2017-06-23, 1998-10-20, 1492-10-12` HOOK STDOUT: * `filename`: An expression with `*.\w{2,4}` format: `index.js`, `detail.html`, `'my_book.pdf'`, `'dfj358h-g9854-fn84n4.tmp'` HOOK STDOUT: * `UUID`: *Universally unique identifier* is a 128-bit number used to identify information in computer systems. Use a format as `xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx`. Ex: `123e4567-e89b-12d3-a456-426655440000` HOOK STDOUT: HOOK STDOUT: That means, wherever you put `/:id` you can use it in your view as param (named `id`). HOOK STDOUT: ```python HOOK STDOUT: url('post/:pk/comment/:id', myview, name="post_comment") HOOK STDOUT: ``` HOOK STDOUT: Your view: HOOK STDOUT: ```python HOOK STDOUT: def myview(request, pk, id): HOOK STDOUT: # Use `pk` (post's) and `id` (comment's) HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: But what if I have two or more id's, or two slugs? What if I wanted to use a custom name for my id's? - Ok, you can use custom names if you end it with `_` + the pattern type. - What?... HOOK STDOUT: ```python HOOK STDOUT: url('post/:post_pk/comment/:comment_id', myview, ...) HOOK STDOUT: # ... HOOK STDOUT: def myview(request, post_pk, comment_id): HOOK STDOUT: # `post_pk` is parsed as a :pk and `comment_id` like an :id HOOK STDOUT: HOOK STDOUT: ``` HOOK STDOUT: Yeah, it sounds good!, but... What if I wanted to use my own patterns? - Easy, any world in the path is of type `:slug` by default, but if you need a custom pattern you can register many as you want: HOOK STDOUT: ```python HOOK STDOUT: from djurl import url, register_pattern HOOK STDOUT: register_pattern('hash', '[a-f0-9]{9}') HOOK STDOUT: # parsed as slug HOOK STDOUT: url('/:user', myUserView), HOOK STDOUT: # custom pattern HOOK STDOUT: url('/:hash', myview), HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: If you have questions, visit our [FAQ's](FAQ.md) or open an *issue*. HOOK STDOUT: HOOK STDOUT: Install HOOK STDOUT: --- HOOK STDOUT: If you want to have fun with this library and integrate it to your project, just type in your terminal: HOOK STDOUT: ``` HOOK STDOUT: $ pip install djurl HOOK STDOUT: ``` HOOK STDOUT: or, clone the repo and type: HOOK STDOUT: ``` HOOK STDOUT: $ python setup.py install HOOK STDOUT: ``` HOOK STDOUT: Enjoy it! HOOK STDOUT: HOOK STDOUT: Testing HOOK STDOUT: --- HOOK STDOUT: Clone the repo and run Djurl tests by: HOOK STDOUT: ``` HOOK STDOUT: $ python setup.py test HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: Contributions HOOK STDOUT: --- HOOK STDOUT: If you've found a bug/error or just have questions, feel free to open an **issue**. And, **Pull requests** are welcome as well. HOOK STDOUT: Don't forget to add your name to [CONTRIBUTORS.md](CONTRIBUTORS.md) HOOK STDOUT: HOOK STDOUT: License HOOK STDOUT: ======= HOOK STDOUT: HOOK STDOUT: Copyright 2017 Christopher Ventura HOOK STDOUT: HOOK STDOUT: Licensed under the Apache License, Version 2.0 (the "License"); HOOK STDOUT: you may not use this file except in compliance with the License. HOOK STDOUT: You may obtain a copy of the License at HOOK STDOUT: HOOK STDOUT: http://www.apache.org/licenses/LICENSE-2.0 HOOK STDOUT: HOOK STDOUT: Unless required by applicable law or agreed to in writing, software HOOK STDOUT: distributed under the License is distributed on an "AS IS" BASIS, HOOK STDOUT: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. HOOK STDOUT: See the License for the specific language governing permissions and HOOK STDOUT: limitations under the License. HOOK STDOUT: Handling django from wheel metadata: Requires-Dist Requirement satisfied: django (installed: django 4.0.2) + RPM_EC=0 ++ jobs -p + exit 0 Executing(%build): /bin/sh -e /var/tmp/rpm-tmp.kgkenm + umask 022 + cd /builddir/build/BUILD + CFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection' + export CFLAGS + CXXFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection' + export CXXFLAGS + FFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -I/usr/lib64/gfortran/modules' + export FFLAGS + FCFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -I/usr/lib64/gfortran/modules' + export FCFLAGS + LDFLAGS='-Wl,-z,relro -Wl,--as-needed -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,--build-id=sha1 -Wl,-dT,/builddir/build/BUILD/djurl-0.2.0/.package_note-python-djurl-0.2.0-1.fc37.x86_64.ld' + export LDFLAGS + LT_SYS_LIBRARY_PATH=/usr/lib64: + export LT_SYS_LIBRARY_PATH + CC=gcc + export CC + CXX=g++ + export CXX + '[' -f /usr/lib/rpm/generate-rpm-note.sh ']' + /usr/lib/rpm/generate-rpm-note.sh python-djurl 0.2.0-1.fc37 x86_64 + cd djurl-0.2.0 + mkdir -p /builddir/build/BUILD/djurl-0.2.0/.pyproject-builddir + CFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection' + LDFLAGS='-Wl,-z,relro -Wl,--as-needed -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,--build-id=sha1 -Wl,-dT,/builddir/build/BUILD/djurl-0.2.0/.package_note-python-djurl-0.2.0-1.fc37.x86_64.ld' + TMPDIR=/builddir/build/BUILD/djurl-0.2.0/.pyproject-builddir + /usr/bin/python3 -m pip wheel --wheel-dir /builddir/build/BUILD/djurl-0.2.0/pyproject-wheeldir --no-deps --use-pep517 --no-build-isolation --disable-pip-version-check --no-clean --progress-bar off --verbose . Processing /builddir/build/BUILD/djurl-0.2.0 Preparing metadata (pyproject.toml): started Running command Preparing metadata (pyproject.toml) /usr/lib/python3.10/site-packages/setuptools/dist.py:723: UserWarning: Usage of dash-separated 'description-file' will not be supported in future versions. Please use the underscore name 'description_file' instead warnings.warn( running dist_info creating /builddir/build/BUILD/djurl-0.2.0/.pyproject-builddir/pip-modern-metadata-74ezk5lc/djurl.egg-info writing /builddir/build/BUILD/djurl-0.2.0/.pyproject-builddir/pip-modern-metadata-74ezk5lc/djurl.egg-info/PKG-INFO writing dependency_links to /builddir/build/BUILD/djurl-0.2.0/.pyproject-builddir/pip-modern-metadata-74ezk5lc/djurl.egg-info/dependency_links.txt writing requirements to /builddir/build/BUILD/djurl-0.2.0/.pyproject-builddir/pip-modern-metadata-74ezk5lc/djurl.egg-info/requires.txt writing top-level names to /builddir/build/BUILD/djurl-0.2.0/.pyproject-builddir/pip-modern-metadata-74ezk5lc/djurl.egg-info/top_level.txt writing manifest file '/builddir/build/BUILD/djurl-0.2.0/.pyproject-builddir/pip-modern-metadata-74ezk5lc/djurl.egg-info/SOURCES.txt' reading manifest file '/builddir/build/BUILD/djurl-0.2.0/.pyproject-builddir/pip-modern-metadata-74ezk5lc/djurl.egg-info/SOURCES.txt' reading manifest template 'MANIFEST.in' writing manifest file '/builddir/build/BUILD/djurl-0.2.0/.pyproject-builddir/pip-modern-metadata-74ezk5lc/djurl.egg-info/SOURCES.txt' creating '/builddir/build/BUILD/djurl-0.2.0/.pyproject-builddir/pip-modern-metadata-74ezk5lc/djurl.dist-info' ![DjUrl - Django urls](/djurlheader.png) [![Build Status](https://travis-ci.org/venturachrisdev/djurl.svg?branch=master)](https://travis-ci.org/venturachrisdev/djurl) === Simple yet helpful library for writing Django urls by an easy, short an intuitive way. Why should I use DjUrl? --- Django routing urls aren't easy to deal with, regular expressions can become a nightmare sometimes. Just imagine dealing with such routes in your `django app`: ```python from django.conf.urls import url from core import BlogView, SinglePostView, SearchResultsView, ArchiveView urlpatterns = [ # => /blog/ url(r'^blog/$', BlogView.as_view(), name="blog"), # => /blog/5 url(r'^blog/(?P[0-9]+)/$', SinglePostView.as_view(), name="singlepost"), # => /blog/search/sometitle url(r'^blog/search/(?P[A-Za-z0-9_-]+)/$', SearchResultsView.as_view(), name="search"), # => /blog/archive/2017/02/12 url(r'^blog/archive/(?P[0-9]{4}-(0?([1-9])|10|11|12)-((0|1|2)?([1-9])|[1-3]0|31))/$', ArchiveView.as_view(), name="archive") ] ``` That's too much work and you lost me in those regex. With **DjUrl** this comes easy, you just need to *express what you want*, **DjUrl will handle the regular expressions for you**: ```python from djurl import url from core import BlogView, SinglePostView, SearchResultsView, ArchiveView urlpatterns = [ url('/blog', BlogView, name="blog"), url('/blog/:id', SinglePostView, name="singlepost"), url('/blog/search/:query', SearchResultsView, name="search"), url('/blog/archive/:date', ArchiveView, name="archive") ] ``` No regex, just clean paths and param names. You can now pass the regex work to DjUrl and concentrate in the *bussiness logic*. It saves you a lot of time and code. *You don't need to worry about the routes anymore*. **Note you don't need to call `as_view` in your CBV's.** DjUrl does this for you as well. Usage --- Now you know what you should use `DjUrl`, It's time to learn how to use it. DjUrl has a list of known/default pattern that you can use in your routes, these are: * `id`: A secuence of characters from 0 to 9. Ej: `1, 12, 454545, 8885500, 8` * `pk`: A primary key, it's like `id` but needed for `Class Based Views`. * `page`: falls in the same category, but you'd use `page` for a better param name. * `slug`: A simple string (alphanumeric characters). * `query`: A search parameter. It allows some special characters that *slug* doesn't. Ex: `hello%20word`, `don%27t_quote-me` * `day`: A number between 01,..., 31. * `month`: A number between 01,...,12. * `year`: A four digits number: `1998, 2017, 2018, 3015, 2020, 1406...` * `date`: An expression with `year-month-day` format: `2017-06-23, 1998-10-20, 1492-10-12` * `filename`: An expression with `*.\w{2,4}` format: `index.js`, `detail.html`, `'my_book.pdf'`, `'dfj358h-g9854-fn84n4.tmp'` * `UUID`: *Universally unique identifier* is a 128-bit number used to identify information in computer systems. Use a format as `xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx`. Ex: `123e4567-e89b-12d3-a456-426655440000` That means, wherever you put `/:id` you can use it in your view as param (named `id`). ```python url('post/:pk/comment/:id', myview, name="post_comment") ``` Your view: ```python def myview(request, pk, id): # Use `pk` (post's) and `id` (comment's) ``` But what if I have two or more id's, or two slugs? What if I wanted to use a custom name for my id's? - Ok, you can use custom names if you end it with `_` + the pattern type. - What?... ```python url('post/:post_pk/comment/:comment_id', myview, ...) # ... def myview(request, post_pk, comment_id): # `post_pk` is parsed as a :pk and `comment_id` like an :id ``` Yeah, it sounds good!, but... What if I wanted to use my own patterns? - Easy, any world in the path is of type `:slug` by default, but if you need a custom pattern you can register many as you want: ```python from djurl import url, register_pattern register_pattern('hash', '[a-f0-9]{9}') # parsed as slug url('/:user', myUserView), # custom pattern url('/:hash', myview), ``` If you have questions, visit our [FAQ's](FAQ.md) or open an *issue*. Install --- If you want to have fun with this library and integrate it to your project, just type in your terminal: ``` $ pip install djurl ``` or, clone the repo and type: ``` $ python setup.py install ``` Enjoy it! Testing --- Clone the repo and run Djurl tests by: ``` $ python setup.py test ``` Contributions --- If you've found a bug/error or just have questions, feel free to open an **issue**. And, **Pull requests** are welcome as well. Don't forget to add your name to [CONTRIBUTORS.md](CONTRIBUTORS.md) License ======= Copyright 2017 Christopher Ventura Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Preparing metadata (pyproject.toml): finished with status 'done' Building wheels for collected packages: djurl Building wheel for djurl (pyproject.toml): started Running command Building wheel for djurl (pyproject.toml) /usr/lib/python3.10/site-packages/setuptools/dist.py:723: UserWarning: Usage of dash-separated 'description-file' will not be supported in future versions. Please use the underscore name 'description_file' instead warnings.warn( running bdist_wheel running build running build_py creating build creating build/lib creating build/lib/djurl copying djurl/__init__.py -> build/lib/djurl running egg_info creating djurl.egg-info writing djurl.egg-info/PKG-INFO writing dependency_links to djurl.egg-info/dependency_links.txt writing requirements to djurl.egg-info/requires.txt writing top-level names to djurl.egg-info/top_level.txt writing manifest file 'djurl.egg-info/SOURCES.txt' reading manifest file 'djurl.egg-info/SOURCES.txt' reading manifest template 'MANIFEST.in' writing manifest file 'djurl.egg-info/SOURCES.txt' installing to build/bdist.linux-x86_64/wheel running install running install_lib creating build/bdist.linux-x86_64 creating build/bdist.linux-x86_64/wheel creating build/bdist.linux-x86_64/wheel/djurl copying build/lib/djurl/__init__.py -> build/bdist.linux-x86_64/wheel/djurl running install_egg_info Copying djurl.egg-info to build/bdist.linux-x86_64/wheel/djurl-0.2.0-py3.10.egg-info running install_scripts creating build/bdist.linux-x86_64/wheel/djurl-0.2.0.dist-info/WHEEL creating '/builddir/build/BUILD/djurl-0.2.0/.pyproject-builddir/pip-wheel-4ztc3jrt/tmpya9jkdaf/djurl-0.2.0-py3-none-any.whl' and adding 'build/bdist.linux-x86_64/wheel' to it adding 'djurl/__init__.py' adding 'djurl-0.2.0.dist-info/METADATA' adding 'djurl-0.2.0.dist-info/WHEEL' adding 'djurl-0.2.0.dist-info/top_level.txt' adding 'djurl-0.2.0.dist-info/RECORD' removing build/bdist.linux-x86_64/wheel ![DjUrl - Django urls](/djurlheader.png) [![Build Status](https://travis-ci.org/venturachrisdev/djurl.svg?branch=master)](https://travis-ci.org/venturachrisdev/djurl) === Simple yet helpful library for writing Django urls by an easy, short an intuitive way. Why should I use DjUrl? --- Django routing urls aren't easy to deal with, regular expressions can become a nightmare sometimes. Just imagine dealing with such routes in your `django app`: ```python from django.conf.urls import url from core import BlogView, SinglePostView, SearchResultsView, ArchiveView urlpatterns = [ # => /blog/ url(r'^blog/$', BlogView.as_view(), name="blog"), # => /blog/5 url(r'^blog/(?P[0-9]+)/$', SinglePostView.as_view(), name="singlepost"), # => /blog/search/sometitle url(r'^blog/search/(?P[A-Za-z0-9_-]+)/$', SearchResultsView.as_view(), name="search"), # => /blog/archive/2017/02/12 url(r'^blog/archive/(?P[0-9]{4}-(0?([1-9])|10|11|12)-((0|1|2)?([1-9])|[1-3]0|31))/$', ArchiveView.as_view(), name="archive") ] ``` That's too much work and you lost me in those regex. With **DjUrl** this comes easy, you just need to *express what you want*, **DjUrl will handle the regular expressions for you**: ```python from djurl import url from core import BlogView, SinglePostView, SearchResultsView, ArchiveView urlpatterns = [ url('/blog', BlogView, name="blog"), url('/blog/:id', SinglePostView, name="singlepost"), url('/blog/search/:query', SearchResultsView, name="search"), url('/blog/archive/:date', ArchiveView, name="archive") ] ``` No regex, just clean paths and param names. You can now pass the regex work to DjUrl and concentrate in the *bussiness logic*. It saves you a lot of time and code. *You don't need to worry about the routes anymore*. **Note you don't need to call `as_view` in your CBV's.** DjUrl does this for you as well. Usage --- Now you know what you should use `DjUrl`, It's time to learn how to use it. DjUrl has a list of known/default pattern that you can use in your routes, these are: * `id`: A secuence of characters from 0 to 9. Ej: `1, 12, 454545, 8885500, 8` * `pk`: A primary key, it's like `id` but needed for `Class Based Views`. * `page`: falls in the same category, but you'd use `page` for a better param name. * `slug`: A simple string (alphanumeric characters). * `query`: A search parameter. It allows some special characters that *slug* doesn't. Ex: `hello%20word`, `don%27t_quote-me` * `day`: A number between 01,..., 31. * `month`: A number between 01,...,12. * `year`: A four digits number: `1998, 2017, 2018, 3015, 2020, 1406...` * `date`: An expression with `year-month-day` format: `2017-06-23, 1998-10-20, 1492-10-12` * `filename`: An expression with `*.\w{2,4}` format: `index.js`, `detail.html`, `'my_book.pdf'`, `'dfj358h-g9854-fn84n4.tmp'` * `UUID`: *Universally unique identifier* is a 128-bit number used to identify information in computer systems. Use a format as `xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx`. Ex: `123e4567-e89b-12d3-a456-426655440000` That means, wherever you put `/:id` you can use it in your view as param (named `id`). ```python url('post/:pk/comment/:id', myview, name="post_comment") ``` Your view: ```python def myview(request, pk, id): # Use `pk` (post's) and `id` (comment's) ``` But what if I have two or more id's, or two slugs? What if I wanted to use a custom name for my id's? - Ok, you can use custom names if you end it with `_` + the pattern type. - What?... ```python url('post/:post_pk/comment/:comment_id', myview, ...) # ... def myview(request, post_pk, comment_id): # `post_pk` is parsed as a :pk and `comment_id` like an :id ``` Yeah, it sounds good!, but... What if I wanted to use my own patterns? - Easy, any world in the path is of type `:slug` by default, but if you need a custom pattern you can register many as you want: ```python from djurl import url, register_pattern register_pattern('hash', '[a-f0-9]{9}') # parsed as slug url('/:user', myUserView), # custom pattern url('/:hash', myview), ``` If you have questions, visit our [FAQ's](FAQ.md) or open an *issue*. Install --- If you want to have fun with this library and integrate it to your project, just type in your terminal: ``` $ pip install djurl ``` or, clone the repo and type: ``` $ python setup.py install ``` Enjoy it! Testing --- Clone the repo and run Djurl tests by: ``` $ python setup.py test ``` Contributions --- If you've found a bug/error or just have questions, feel free to open an **issue**. And, **Pull requests** are welcome as well. Don't forget to add your name to [CONTRIBUTORS.md](CONTRIBUTORS.md) License ======= Copyright 2017 Christopher Ventura Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Building wheel for djurl (pyproject.toml): finished with status 'done' Created wheel for djurl: filename=djurl-0.2.0-py3-none-any.whl size=5252 sha256=5fc1f770a213690270f9182eddf241678739d93031880d78db6346c328688a68 Stored in directory: /builddir/.cache/pip/wheels/5d/bc/9e/9adb252fd1721e520986f573a71db6cb758cac4541d010b102 Successfully built djurl + RPM_EC=0 ++ jobs -p + exit 0 Executing(%install): /bin/sh -e /var/tmp/rpm-tmp.pFXXjU + umask 022 + cd /builddir/build/BUILD + '[' /builddir/build/BUILDROOT/python-djurl-0.2.0-1.fc37.x86_64 '!=' / ']' + rm -rf /builddir/build/BUILDROOT/python-djurl-0.2.0-1.fc37.x86_64 ++ dirname /builddir/build/BUILDROOT/python-djurl-0.2.0-1.fc37.x86_64 + mkdir -p /builddir/build/BUILDROOT + mkdir /builddir/build/BUILDROOT/python-djurl-0.2.0-1.fc37.x86_64 + CFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection' + export CFLAGS + CXXFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection' + export CXXFLAGS + FFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -I/usr/lib64/gfortran/modules' + export FFLAGS + FCFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -I/usr/lib64/gfortran/modules' + export FCFLAGS + LDFLAGS='-Wl,-z,relro -Wl,--as-needed -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,--build-id=sha1 -Wl,-dT,/builddir/build/BUILD/djurl-0.2.0/.package_note-python-djurl-0.2.0-1.fc37.x86_64.ld' + export LDFLAGS + LT_SYS_LIBRARY_PATH=/usr/lib64: + export LT_SYS_LIBRARY_PATH + CC=gcc + export CC + CXX=g++ + export CXX + cd djurl-0.2.0 ++ ls /builddir/build/BUILD/djurl-0.2.0/pyproject-wheeldir/djurl-0.2.0-py3-none-any.whl ++ sed -E 's/([^-]+)-([^-]+)-.+\.whl/\1==\2/' ++ xargs basename --multiple + specifier=djurl==0.2.0 + TMPDIR=/builddir/build/BUILD/djurl-0.2.0/.pyproject-builddir + /usr/bin/python3 -m pip install --root /builddir/build/BUILDROOT/python-djurl-0.2.0-1.fc37.x86_64 --no-deps --disable-pip-version-check --progress-bar off --verbose --ignore-installed --no-warn-script-location --no-index --no-cache-dir --find-links /builddir/build/BUILD/djurl-0.2.0/pyproject-wheeldir djurl==0.2.0 Using pip 22.0.3 from /usr/lib/python3.10/site-packages/pip (python 3.10) Looking in links: /builddir/build/BUILD/djurl-0.2.0/pyproject-wheeldir Processing ./pyproject-wheeldir/djurl-0.2.0-py3-none-any.whl Installing collected packages: djurl Successfully installed djurl-0.2.0 + '[' -d /builddir/build/BUILDROOT/python-djurl-0.2.0-1.fc37.x86_64/usr/bin ']' + rm -f /builddir/build/BUILD/pyproject-ghost-distinfo + site_dirs=() + '[' -d /builddir/build/BUILDROOT/python-djurl-0.2.0-1.fc37.x86_64/usr/lib/python3.10/site-packages ']' + site_dirs+=("/usr/lib/python3.10/site-packages") + '[' /builddir/build/BUILDROOT/python-djurl-0.2.0-1.fc37.x86_64/usr/lib64/python3.10/site-packages '!=' /builddir/build/BUILDROOT/python-djurl-0.2.0-1.fc37.x86_64/usr/lib/python3.10/site-packages ']' + '[' -d /builddir/build/BUILDROOT/python-djurl-0.2.0-1.fc37.x86_64/usr/lib64/python3.10/site-packages ']' + for site_dir in ${site_dirs[@]} + for distinfo in /builddir/build/BUILDROOT/python-djurl-0.2.0-1.fc37.x86_64$site_dir/*.dist-info + echo '%ghost /usr/lib/python3.10/site-packages/djurl-0.2.0.dist-info' + sed -i s/pip/rpm/ /builddir/build/BUILDROOT/python-djurl-0.2.0-1.fc37.x86_64/usr/lib/python3.10/site-packages/djurl-0.2.0.dist-info/INSTALLER + PYTHONPATH=/usr/lib/rpm/redhat + /usr/bin/python3 -B /usr/lib/rpm/redhat/pyproject_preprocess_record.py --buildroot /builddir/build/BUILDROOT/python-djurl-0.2.0-1.fc37.x86_64 --record /builddir/build/BUILDROOT/python-djurl-0.2.0-1.fc37.x86_64/usr/lib/python3.10/site-packages/djurl-0.2.0.dist-info/RECORD --output /builddir/build/BUILD/pyproject-record + rm -fv /builddir/build/BUILDROOT/python-djurl-0.2.0-1.fc37.x86_64/usr/lib/python3.10/site-packages/djurl-0.2.0.dist-info/RECORD removed '/builddir/build/BUILDROOT/python-djurl-0.2.0-1.fc37.x86_64/usr/lib/python3.10/site-packages/djurl-0.2.0.dist-info/RECORD' + rm -fv /builddir/build/BUILDROOT/python-djurl-0.2.0-1.fc37.x86_64/usr/lib/python3.10/site-packages/djurl-0.2.0.dist-info/REQUESTED removed '/builddir/build/BUILDROOT/python-djurl-0.2.0-1.fc37.x86_64/usr/lib/python3.10/site-packages/djurl-0.2.0.dist-info/REQUESTED' ++ wc -l /builddir/build/BUILD/pyproject-ghost-distinfo ++ cut -f1 '-d ' + lines=1 + '[' 1 -ne 1 ']' + /usr/bin/python3 /usr/lib/rpm/redhat/pyproject_save_files.py --output-files /builddir/build/BUILD/pyproject-files --output-modules /builddir/build/BUILD/pyproject-modules --buildroot /builddir/build/BUILDROOT/python-djurl-0.2.0-1.fc37.x86_64 --sitelib /usr/lib/python3.10/site-packages --sitearch /usr/lib64/python3.10/site-packages --python-version 3.10 --pyproject-record /builddir/build/BUILD/pyproject-record --prefix /usr '*' +auto + /usr/bin/find-debuginfo -j2 --strict-build-id -m -i --build-id-seed 0.2.0-1.fc37 --unique-debug-suffix -0.2.0-1.fc37.x86_64 --unique-debug-src-base python-djurl-0.2.0-1.fc37.x86_64 --run-dwz --dwz-low-mem-die-limit 10000000 --dwz-max-die-limit 110000000 -S debugsourcefiles.list /builddir/build/BUILD/djurl-0.2.0 find: 'debug': No such file or directory + /usr/lib/rpm/check-buildroot + /usr/lib/rpm/redhat/brp-ldconfig + /usr/lib/rpm/brp-compress + /usr/lib/rpm/redhat/brp-strip-lto /usr/bin/strip + /usr/lib/rpm/brp-strip-static-archive /usr/bin/strip + /usr/lib/rpm/check-rpaths + /usr/lib/rpm/redhat/brp-mangle-shebangs + /usr/lib/rpm/redhat/brp-python-bytecompile '' 1 0 Bytecompiling .py files below /builddir/build/BUILDROOT/python-djurl-0.2.0-1.fc37.x86_64/usr/lib/python3.10 using python3.10 + /usr/lib/rpm/redhat/brp-python-hardlink Executing(%check): /bin/sh -e /var/tmp/rpm-tmp.X90CVR + umask 022 + cd /builddir/build/BUILD + CFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection' + export CFLAGS + CXXFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection' + export CXXFLAGS + FFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -I/usr/lib64/gfortran/modules' + export FFLAGS + FCFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -I/usr/lib64/gfortran/modules' + export FCFLAGS + LDFLAGS='-Wl,-z,relro -Wl,--as-needed -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,--build-id=sha1 -Wl,-dT,/builddir/build/BUILD/djurl-0.2.0/.package_note-python-djurl-0.2.0-1.fc37.x86_64.ld' + export LDFLAGS + LT_SYS_LIBRARY_PATH=/usr/lib64: + export LT_SYS_LIBRARY_PATH + CC=gcc + export CC + CXX=g++ + export CXX + '[' -f /usr/lib/rpm/generate-rpm-note.sh ']' + /usr/lib/rpm/generate-rpm-note.sh python-djurl 0.2.0-1.fc37 x86_64 + cd djurl-0.2.0 + '[' '!' -f /builddir/build/BUILD/pyproject-modules ']' + PATH=/builddir/build/BUILDROOT/python-djurl-0.2.0-1.fc37.x86_64/usr/bin:/builddir/.local/bin:/builddir/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/sbin + PYTHONPATH=/builddir/build/BUILDROOT/python-djurl-0.2.0-1.fc37.x86_64/usr/lib64/python3.10/site-packages:/builddir/build/BUILDROOT/python-djurl-0.2.0-1.fc37.x86_64/usr/lib/python3.10/site-packages + _PYTHONSITE=/builddir/build/BUILDROOT/python-djurl-0.2.0-1.fc37.x86_64/usr/lib64/python3.10/site-packages:/builddir/build/BUILDROOT/python-djurl-0.2.0-1.fc37.x86_64/usr/lib/python3.10/site-packages + PYTHONDONTWRITEBYTECODE=1 + /usr/bin/python3 -s /usr/lib/rpm/redhat/import_all_modules.py -f /builddir/build/BUILD/pyproject-modules -t Check import: djurl + RPM_EC=0 ++ jobs -p + exit 0 Processing files: python3-djurl-0.2.0-1.fc37.noarch Provides: python-djurl = 0.2.0-1.fc37 python3-djurl = 0.2.0-1.fc37 python3.10-djurl = 0.2.0-1.fc37 python3.10dist(djurl) = 0.2 python3dist(djurl) = 0.2 Requires(rpmlib): rpmlib(CompressedFileNames) <= 3.0.4-1 rpmlib(FileDigests) <= 4.6.0-1 rpmlib(PartialHardlinkSets) <= 4.0.4-1 rpmlib(PayloadFilesHavePrefix) <= 4.0-1 Requires: python(abi) = 3.10 python3.10dist(django) Checking for unpackaged file(s): /usr/lib/rpm/check-files /builddir/build/BUILDROOT/python-djurl-0.2.0-1.fc37.x86_64 Wrote: /builddir/build/SRPMS/python-djurl-0.2.0-1.fc37.src.rpm Wrote: /builddir/build/RPMS/python3-djurl-0.2.0-1.fc37.noarch.rpm Executing(%clean): /bin/sh -e /var/tmp/rpm-tmp.MAjZmY + umask 022 + cd /builddir/build/BUILD + cd djurl-0.2.0 + /usr/bin/rm -rf /builddir/build/BUILDROOT/python-djurl-0.2.0-1.fc37.x86_64 + RPM_EC=0 ++ jobs -p + exit 0 Child return code was: 0