Repository: vitalik/django-ninja

Issue:
Schema doesn't render properly
![Screenshot from 2021-10-03 10-31-49](https://user-images.githubusercontent.com/37798612/135746628-277455b5-d19a-424e-8caa-de4a58ec3557.png)

Code:

```python
def forgot_password(request: HttpRequest, email: EmailStr = Form(...)):
    ...

# And

def reset_password(
    request: HttpRequest,
    token: str,
    password: constr(strip_whitespace=True, min_length=8) = Form(...),
):
    ...
```



Discussion:

Patch:
diff --git a/ninja/openapi/schema.py b/ninja/openapi/schema.py
index 9232f18..795f0d1 100644
--- a/ninja/openapi/schema.py
+++ b/ninja/openapi/schema.py
@@ -230,12 +230,9 @@ class OpenAPISchema(dict):
         if len(models) == 1:
             model = models[0]
             content_type = BODY_CONTENT_TYPES[model._param_source]
-            if model._param_source == "file":
-                schema, required = self._create_schema_from_model(
-                    model, remove_level=False
-                )
-            else:
-                schema, required = self._create_schema_from_model(model)
+            schema, required = self._create_schema_from_model(
+                model, remove_level=model._param_source == "body"
+            )
         else:
             schema, content_type = self._create_multipart_schema_from_models(models)
             required = True


Test patch:
diff --git a/tests/test_openapi_schema.py b/tests/test_openapi_schema.py
index ba83386..537ba7a 100644
--- a/tests/test_openapi_schema.py
+++ b/tests/test_openapi_schema.py
@@ -62,6 +62,11 @@ def method_form(request, data: Payload = Form(...)):
     return dict(i=data.i, f=data.f)
 
 
+@api.post("/test-form-single", response=Response)
+def method_form_single(request, data: float = Form(...)):
+    return dict(i=int(data), f=data)
+
+
 @api.post("/test-form-body", response=Response)
 def method_form_body(request, i: int = Form(10), s: str = Body("10")):
     return dict(i=i, s=s)
@@ -358,6 +363,34 @@ def test_schema_form(schema):
     }
 
 
+def test_schema_single(schema):
+    method_list = schema["paths"]["/api/test-form-single"]["post"]
+
+    assert method_list["requestBody"] == {
+        "content": {
+            "application/x-www-form-urlencoded": {
+                "schema": {
+                    "properties": {"data": {"title": "Data", "type": "number"}},
+                    "required": ["data"],
+                    "title": "FormParams",
+                    "type": "object",
+                }
+            }
+        },
+        "required": True,
+    }
+    assert method_list["responses"] == {
+        200: {
+            "description": "OK",
+            "content": {
+                "application/json": {
+                    "schema": {"$ref": "#/components/schemas/Response"}
+                }
+            },
+        }
+    }
+
+
 def test_schema_form_body(schema):
     method_list = schema["paths"]["/api/test-form-body"]["post"]
 
diff --git a/tests/test_wraps.py b/tests/test_wraps.py
index 69b0ee6..98fd0c4 100644
--- a/tests/test_wraps.py
+++ b/tests/test_wraps.py
@@ -1,4 +1,5 @@
 from functools import wraps
+from unittest import mock
 
 import pytest
 
@@ -60,10 +61,12 @@ def get_text_bad(request):
     return "Hello World"
 
 
-@router.get("/path-bad/{item_id}")
-@a_bad_test_wrapper
-def get_id_bad(request, item_id):
-    return item_id
+with mock.patch("ninja.signature.details.warnings.warn_explicit"):
+
+    @router.get("/path-bad/{item_id}")
+    @a_bad_test_wrapper
+    def get_id_bad(request, item_id):
+        return item_id
 
 
 @router.get("/query-bad")
@@ -72,10 +75,12 @@ def get_query_type_bad(request, query: int):
     return f"foo bar {query}"
 
 
-@router.get("/path-query-bad/{item_id}")
-@a_bad_test_wrapper
-def get_query_id_bad(request, item_id, query: int):
-    return f"foo bar {item_id} {query}"
+with mock.patch("ninja.signature.details.warnings.warn_explicit"):
+
+    @router.get("/path-query-bad/{item_id}")
+    @a_bad_test_wrapper
+    def get_query_id_bad(request, item_id, query: int):
+        return f"foo bar {item_id} {query}"
 
 
 @pytest.mark.parametrize(