You defined a string with a re'..' prefix. But Python does not have a re'..' prefix.
It has an r'..' prefix, and this does not mean "regex", but "raw". It does not mean you construct a regex, but more that if you write for example r'foo\nbar', you did not write a new line character ('\n'), but you write a backslash r'\' (or '\\' for a regular string) followed by a 'n' character. This is necessary, since if you construct a regex, the backslashes should still be individual characters.
You can thus rewrite it to:
urlpatterns = [
# r instead of re
re_path(r'^details/(?P\d+)/$', views.details),
path('', views.index)
]
Python also has f'..' strings (that can contain variables that are then formatted), and b'..' strings (for binary strings), but those do not really matter in the case of urlpatterns.
You thus do not per se need to use the r'..' prefix at all. But in that case, you have to ensure that you escape backslashes yourself. This makes it harder to write and read. Therefore r'..' is probably the best way to write regexes.
r'..'notre'..'.