I took your advice but no joy. AND I don't know why!

The "invoice" is in fact the receipt model and receipt.get_absolute_url just wants the pk value to display what the customer paid.

def get_absolute_url(self):
        """ Show the Invoice receipt """
        return f"/invoice/{self.id}/"

... which matches the re_path for "invoice_view" below as well as the model view in the Admin.

Looking at the Invoice/Receipt in the Admin the url is ...

     http://localhost:8088/admin/billing/receipt/67/change/

HOWEVER when rolling the mouse across the (View on site) button in the Admin, I see a strange URL which actually works!

     http://localhost:8088/admin/r/49/67/            # no idea what the r/49 is

... and when (View on site) is clicked the resulting Invoice/Receipt appears exactly as expected with url ...

     http://localhost:8088/invoice/67/

So if I take your advice and use ...


would be `path("invoice/<int:pk>", billing_views.invoice_view, name="invoice_view")

... 'View on site' barfs with ...


 Page not found (404)

Request Method:         GET
Request URL:    http://localhost:8088/invoice/67/

Using the URLconf defined in |xxx.urls|, Django tried these URL patterns, in this order:

1. ^admin/filebrowser/
2. ^tinymce/
3. ^500/$
4. ^401/$
5. ^403/$
6. ^404/$
7. ^admin/500/$
8. ^admin/401/$
9. ^admin/403/$
10. ^admin/404/$
11. invoice/<int:pk> [name='invoice_view']
12. success$ [name='success_view']
13. payment$ [name='payment_view']
   <snip>

All this by the way is with Django 3.2.9. Version 3.2.10 to 3.2.13 all fail as per my original request for advice to which you suggested I file a bug.

I'm somewhat baffled.

As for filing a bug I'm not sure what to say.

For the moment I'm stuck with re_path and version 3.2.9 in production.

Thanks again for listening and if you think I should post more code I'm happy to do that.

Cheers

Mike



On 21/05/2022 11:38 pm, Jason wrote:
https://docs.djangoproject.com/en/4.0/ref/urls/#django.urls.path

This was one of the additions in 2.0, and from what it seems like, you're not doing anything specific with regex that cannot be done with a path alternative.

ie,

 re_path(r"invoice/(?P<pk>\d+)/$", billing_views.invoice_view, name="invoice_view"),

would be `path("invoice/<int:pk>", billing_views.invoice_view, name="invoice_view")

wonder if this works for you.

also, this might be worth opening a bug ticket about, since this seems like a regression.


On 21/05/2022 11:04 am, Mike Dewhirst wrote:
On 20/05/2022 11:21 pm, Jason wrote:
are you using re_path for the url in question?

Thanks for responding Jason, yes! Here are my relevant lines ...

    re_path(r"invoice/(?P<pk>\d+)/$", billing_views.invoice_view, name="invoice_view"),
    # no trailing slash or the payment system barfs
    re_path(r"success$", billing_views.success_view, name="success_view"),
    # no trailing slash or the payment system barfs
    re_path(r"payment$", billing_views.payment_view, name="payment_view"),

I'm not particularly keen on re because I have to study the docs to make sense of it every time. If there is an easier way I'll do it!


you can see the backport change here : https://github.com/django/django/commit/d4dcd5b9dd9e462fec8220e33e3e6c822b7e88a6

I looked at the tests and see they are actually looking for '\n' and I'm sure none of my urls end that way.

Cheers

mike


On Thursday, May 19, 2022 at 11:14:25 PM UTC-4 Mike Dewhirst wrote:

    My billing (Stripe) mechanism is working right up until Django
    3.2.9 -
    which is where I'm stumped at the moment.

    Django 3.2.10 https://docs.djangoproject.com/en/3.2/releases/3.2.10/
    indicate a URL with a trailing newline can bypass
    upstream access control based on URL paths.

    Sadly, I am not aware of any such upstream access control.

    I have tried to repair it with fixid() within change_view() where
    object_id occurs but that doesn't achieve anything.

    def fixid(txt):
        try:
            return str(txt).split("/")[0]
        except ValueError:
            pass
        return txt

    How can I fix the following error and move forward to 3.2.13?

    Many thanks

    Mike
    - - - - - - - -

    Exception Type: ValueError at
    /admin/chemical/chemical/29/change/payment/change/
    Exception Value: Field 'id' expected a number but got
    '29/change/payment'.

    Environment:

    Request Method: GET
    Request URL:
    http://localhost:8088/admin/chemical/chemical/29/change/payment/change/


    Django Version: 3.2.13
    Python Version: 3.8.3
    Installed Applications:
    ['filebrowser',
     'django.contrib.auth',
     'django.contrib.contenttypes',
     'django.contrib.sessions',
     'django.contrib.messages',
     'django.contrib.admin',
     'django.contrib.admindocs',
     'django.contrib.staticfiles',
     'django.contrib.sites',
     'django.contrib.sitemaps',
     'tinymce',
     'billing',
     'chemical',
     'common',
     'company',
     'credit',
     'refer',
     'report']
    Installed Middleware:
    ['django.middleware.security.SecurityMiddleware',
     'django.middleware.cache.UpdateCacheMiddleware',
     'django.contrib.sessions.middleware.SessionMiddleware',
     'django.middleware.locale.LocaleMiddleware',
     'django.middleware.common.CommonMiddleware',
     'django.middleware.csrf.CsrfViewMiddleware',
     'django.contrib.auth.middleware.AuthenticationMiddleware',
     'django.contrib.messages.middleware.MessageMiddleware',
     'django.contrib.admindocs.middleware.XViewMiddleware',
     'django.middleware.clickjacking.XFrameOptionsMiddleware',
     'pwned_passwords_django.middleware.PwnedPasswordsMiddleware',
     'django.middleware.cache.FetchFromCacheMiddleware']



    Traceback (most recent call last):
      File
    
"D:\Users\mike\envs\xxai\lib\site-packages\django\db\models\fields\__init__.py",

    line 1823, in get_prep_value
        return int(value)

    The above exception (invalid literal for int() with base 10:
    '29/change/payment') was the direct cause of the following
    exception:
      File
    
"D:\Users\mike\envs\xxai\lib\site-packages\django\core\handlers\exception.py",

    line 47, in inner
        response = get_response(request)
      File
    "D:\Users\mike\envs\xxai\lib\site-packages\django\core\handlers\base.py",

    line 181, in _get_response
        response = wrapped_callback(request, *callback_args,
    **callback_kwargs)
      File
    "D:\Users\mike\envs\xxai\lib\site-packages\django\contrib\admin\options.py",

    line 616, in wrapper
        return self.admin_site.admin_view(view)(*args, **kwargs)
      File
    "D:\Users\mike\envs\xxai\lib\site-packages\django\utils\decorators.py",

    line 130, in _wrapped_view
        response = view_func(request, *args, **kwargs)
      File
    
"D:\Users\mike\envs\xxai\lib\site-packages\django\views\decorators\cache.py",

    line 44, in _wrapped_view_func
        response = view_func(request, *args, **kwargs)
      File
    "D:\Users\mike\envs\xxai\lib\site-packages\django\contrib\admin\sites.py",

    line 232, in inner
        return view(request, *args, **kwargs)
      File "D:\Users\mike\envs\xxai\aicis\chemical\admin.py", line
    268, in
    change_view
        chemical = Chemical.objects.get(id=object_id)
      File
    "D:\Users\mike\envs\xxai\lib\site-packages\django\db\models\manager.py",

    line 85, in manager_method
        return getattr(self.get_queryset(), name)(*args, **kwargs)
      File
    "D:\Users\mike\envs\xxai\lib\site-packages\django\db\models\query.py",

    line 424, in get
        clone = self._chain() if self.query.combinator else
    self.filter(*args, **kwargs)
      File
    "D:\Users\mike\envs\xxai\lib\site-packages\django\db\models\query.py",

    line 941, in filter
        return self._filter_or_exclude(False, args, kwargs)
      File
    "D:\Users\mike\envs\xxai\lib\site-packages\django\db\models\query.py",

    line 961, in _filter_or_exclude
        clone._filter_or_exclude_inplace(negate, args, kwargs)
      File
    "D:\Users\mike\envs\xxai\lib\site-packages\django\db\models\query.py",

    line 968, in _filter_or_exclude_inplace
        self._query.add_q(Q(*args, **kwargs))
      File
    "D:\Users\mike\envs\xxai\lib\site-packages\django\db\models\sql\query.py",

    line 1416, in add_q
        clause, _ = self._add_q(q_object, self.used_aliases)
      File
    "D:\Users\mike\envs\xxai\lib\site-packages\django\db\models\sql\query.py",

    line 1435, in _add_q
        child_clause, needed_inner = self.build_filter(
      File
    "D:\Users\mike\envs\xxai\lib\site-packages\django\db\models\sql\query.py",

    line 1370, in build_filter
        condition = self.build_lookup(lookups, col, value)
      File
    "D:\Users\mike\envs\xxai\lib\site-packages\django\db\models\sql\query.py",

    line 1216, in build_lookup
        lookup = lookup_class(lhs, rhs)
      File
    "D:\Users\mike\envs\xxai\lib\site-packages\django\db\models\lookups.py",

    line 25, in __init__
        self.rhs = self.get_prep_lookup()
      File
    "D:\Users\mike\envs\xxai\lib\site-packages\django\db\models\lookups.py",

    line 77, in get_prep_lookup
        return self.lhs.output_field.get_prep_value(self.rhs)
      File
    
"D:\Users\mike\envs\xxai\lib\site-packages\django\db\models\fields\__init__.py",

    line 1825, in get_prep_value
        raise e.__class__(

    Exception Type: ValueError at
    /admin/chemical/chemical/29/change/payment/change/
    Exception Value: Field 'id' expected a number but got
    '29/change/payment'.



-- Signed email is an absolute defence against phishing. This email has
    been signed with my private key. If you import my public key you can
    automatically decrypt my signature and be sure it came from me. Just
    ask and I'll send it to you. Your email software can handle signing.

--
You received this message because you are subscribed to the Google Groups "Django users" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/8209a97f-3e62-4902-aec7-a4415c5968f6n%40googlegroups.com <https://groups.google.com/d/msgid/django-users/8209a97f-3e62-4902-aec7-a4415c5968f6n%40googlegroups.com?utm_medium=email&utm_source=footer>.


--
Signed email is an absolute defence against phishing. This email has
been signed with my private key. If you import my public key you can
automatically decrypt my signature and be sure it came from me. Just
ask and I'll send it to you. Your email software can handle signing.
--
You received this message because you are subscribed to the Google Groups "Django users" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/14cb3e24-f158-e689-2354-b2adaea07a8c%40dewhirst.com.au <https://groups.google.com/d/msgid/django-users/14cb3e24-f158-e689-2354-b2adaea07a8c%40dewhirst.com.au?utm_medium=email&utm_source=footer>.


--
Signed email is an absolute defence against phishing. This email has
been signed with my private key. If you import my public key you can
automatically decrypt my signature and be sure it came from me. Just
ask and I'll send it to you. Your email software can handle signing.

--
You received this message because you are subscribed to the Google Groups "Django 
users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/f7aeefb6-65e4-3203-8c64-c978054ea49d%40dewhirst.com.au.

Attachment: OpenPGP_signature
Description: OpenPGP digital signature

Reply via email to