Repository: vitalik/django-ninja

Issue:
[BUG] Reverse url names are not auto generated
**Describe the bug**
Reverse resolution of urls described on https://django-ninja.rest-framework.com/tutorial/urls/ does not work for me. By inspecting the generated resolver, I discovered, that views that do not explicitly specify `url_name` do not have a name generated at all. View function name is not used.

**Versions (please complete the following information):**
 - Python version: 3.8
 - Django version: 3.2
 - Django-Ninja version: 0.17.0


Discussion:

Patch:
diff --git a/docs/docs/tutorial/urls.md b/docs/docs/tutorial/urls.md
index 24084bf..c02f8d1 100644
--- a/docs/docs/tutorial/urls.md
+++ b/docs/docs/tutorial/urls.md
@@ -18,6 +18,8 @@ def index(request):
 index_url = reverse_lazy("api-1.0.0:index")
 ```
 
+This implicit URL name will only be set for the first operation for each API path.  If you *don't* want any implicit reverse URL name generated, just explicitly specify `url_name=""` (an empty string) on the method decorator.
+
 ### Changing the URL name
 
 Rather than using the default URL name, you can specficy it explicitly as a property on the method decorator.
@@ -29,6 +31,9 @@ def users(request):
 
 users_url = reverse_lazy("api-1.0.0:user_list")
 ```
+
+This will override any implicit URL name to this API path.
+
 ### Customizing the namespace
 
 The default URL namespace is built by prepending the Schema's version with `"api-"`, however you can explicitly specify the namespace by overriding the `urls_namespace` attribute of the `NinjaAPI` Schema class.
diff --git a/ninja/operation.py b/ninja/operation.py
index 1fe1b42..30ca2df 100644
--- a/ninja/operation.py
+++ b/ninja/operation.py
@@ -278,6 +278,10 @@ class PathView:
         url_name: Optional[str] = None,
         include_in_schema: bool = True,
     ) -> Operation:
+        # If the url_name was not provided, and it hasn't already been set yet,
+        # use the function name as the implicit url name.
+        if url_name is None and not self.url_name:
+            url_name = view_func.__name__
         if url_name:
             self.url_name = url_name
 


Test patch:
diff --git a/tests/demo_project/someapp/api.py b/tests/demo_project/someapp/api.py
index d7f8d88..d4cbee9 100644
--- a/tests/demo_project/someapp/api.py
+++ b/tests/demo_project/someapp/api.py
@@ -31,6 +31,11 @@ def list_events(request):
     return list(Event.objects.all())
 
 
+@router.delete("")
+def delete_events(request):
+    Event.objects.all().delete()
+
+
 @router.get("/{id}", response=EventSchema)
 def get_event(request, id: int):
     event = get_object_or_404(Event, id=id)
diff --git a/tests/test_django_models.py b/tests/test_django_models.py
index 22261d9..8f18b3c 100644
--- a/tests/test_django_models.py
+++ b/tests/test_django_models.py
@@ -24,10 +24,19 @@ def test_with_client(client: Client):
 
 
 def test_reverse():
-    # check that url reversing works
+    """
+    Check that url reversing works.
+    """
     assert reverse("api-1.0.0:event-create-url-name") == "/api/events/create"
 
 
+def test_reverse_implicit():
+    """
+    Check that implicit url reversing works.
+    """
+    assert reverse("api-1.0.0:list_events") == "/api/events"
+
+
 def json_payload(data):
     import json