Skip to content

Commit

Permalink
Introduced extra optional arguments when creating From instance (#61)…
Browse files Browse the repository at this point in the history
… 🪬

* introduced request GET params at init

* flake8

* pass any extra optional argument into `Form` instance
  • Loading branch information
Serbel97 authored Mar 24, 2023
1 parent b0c4d5f commit 3aac8d2
Show file tree
Hide file tree
Showing 10 changed files with 262 additions and 189 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## 1.0.0-rc.9 : 22.03.2023

- **Added**: Introduced extra optional arguments when creating `From` instance

## 1.0.0-rc.8 : 14.03.2023

- **Added**: `GeoJSON` field introduced
Expand Down
11 changes: 9 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ a huge boilerplate. Also, the whole HTML thing was pretty useless in my RESTful
I wanted to:

- define my requests as object (`Form`),
- pass the request to my defined object (`form = Form.create_from_request(request)`),
- pass the request with optional arguments to my defined object (`form = Form.create_from_request(request, param=param)`),
- validate my request `form.is_valid()`,
- extract data `form.clean_data` property.

Expand Down Expand Up @@ -178,13 +178,20 @@ class AlbumForm(Form):
def clean_year(self):
if self.cleaned_data['year'] == 1992:
raise ValidationError("Year 1992 is forbidden!", 'forbidden-value')
if 'param' not in self.extras:
self.add_error(
('param', ),
ValidationError("You can use extra optional arguments in form validation!", code='param-where')
)
return self.cleaned_data['year']

def clean(self):
if (self.cleaned_data['year'] == 1998) and (self.cleaned_data['artist']['name'] == "Nirvana"):
raise ValidationError("Sounds like a bullshit", code='time-traveling')
if not self._request.user.is_authenticated():
raise ValidationError("You can use request in form validation!")
if 'param' not in self.extras:
raise ValidationError("You can use extra optional arguments in form validation!")
return self.cleaned_data


Expand All @@ -193,7 +200,7 @@ class AlbumForm(Form):
Django view example
"""
def create_album(request):
form = AlbumForm.create_from_request(request)
form = AlbumForm.create_from_request(request, param=request.GET.get('param'))
if not form.is_valid():
# Process your validation error
print(form.errors)
Expand Down
7 changes: 4 additions & 3 deletions django_api_forms/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@


class BaseForm:
def __init__(self, data=None, request=None, settings: Settings = None):
def __init__(self, data=None, request=None, settings: Settings = None, **kwargs):
if data is None:
self._data = {}
else:
Expand All @@ -24,6 +24,7 @@ def __init__(self, data=None, request=None, settings: Settings = None):
self.cleaned_data = None
self._request = request
self.settings = settings or Settings()
self.extras = kwargs

if isinstance(self.Meta, type):
if hasattr(self.Meta, 'field_type_strategy'):
Expand Down Expand Up @@ -57,7 +58,7 @@ def __iter__(self):
yield self[name]

@classmethod
def create_from_request(cls, request):
def create_from_request(cls, request, **kwargs):
"""
:rtype: BaseForm
"""
Expand All @@ -80,7 +81,7 @@ def create_from_request(cls, request):
parser = resolve_from_path(settings.PARSERS[content_type])
data = parser(request.body)

return cls(data, request, settings)
return cls(data, request, settings, **kwargs)

@property
def dirty(self) -> List:
Expand Down
2 changes: 1 addition & 1 deletion django_api_forms/version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '1.0.0-rc.8'
__version__ = '1.0.0-rc.9'
10 changes: 9 additions & 1 deletion docs/example.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,21 +111,29 @@ class AlbumForm(Form):
metadata = DictionaryField(value_field=fields.DateTimeField())

def clean_year(self):
if 'param' not in self.extras:
raise ValidationError("You can use request GET params in form validation!")

if self.cleaned_data['year'] == 1992:
raise ValidationError("Year 1992 is forbidden!", 'forbidden-value')
return self.cleaned_data['year']

def clean(self):
if (self.cleaned_data['year'] == 1998) and (self.cleaned_data['artist']['name'] == "Nirvana"):
raise ValidationError("Sounds like a bullshit", code='time-traveling')
if 'param' not in self.extras:
self.add_error(
('param', ),
ValidationError("You can use extra optional arguments in form validation!", code='param-where')
)
return self.cleaned_data


"""
Django view example
"""
def create_album(request):
form = AlbumForm.create_from_request(request)
form = AlbumForm.create_from_request(request, param=request.GET.get('param'))
if not form.is_valid():
# Process your validation error
print(form.errors)
Expand Down
3 changes: 2 additions & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ a huge boilerplate. Also, the whole HTML thing was pretty useless in my RESTful
I wanted to:

- define my requests as object (`Form`),
- pass the request to my defined object (`form = Form.create_from_request(request)`),
- pass the request to my defined object (`form = Form.create_from_request(request, param=param))`),
- you can also pass any extra optional arguments
- validate my request `form.is_valid()`,
- extract data `form.clean_data` property.

Expand Down
15 changes: 13 additions & 2 deletions docs/tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,14 @@ models)

You can create form objects using class method `Form.create_from_request(request: Request) -> Form` which creates form
instance from Django requests using appropriate parser from
[Content-Type](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type) HTTP header.
[Content-Type](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type) HTTP header. You can also pass
any extra argument into `Form.create_from_request(request, param1=request.GET.get('param'), param2=param2) -> Form`

```python
from tests.testapp.forms import AlbumForm

def my_view(request):
form = AlbumForm.create_from_request(request)
form = AlbumForm.create_from_request(request=request, param=request.GET.get('param'))
```

Library by default keeps configuration for handling:
Expand Down Expand Up @@ -88,6 +89,8 @@ This process is much more simple than in classic Django form. It consists of:
using `Form.add_error()`). `Form.clean` is only called when there are no errors from previous section.

Normalized data are available in `Form.clean_data` property (keys suppose to correspond with values from `Form.dirty`).
Extra optional arguments are available in `Form.extras` property (keys suppose to correspond with values
from `Form` initialization)

Validation errors are presented for each field in `Form.errors: List[ValidationError]` property after
`Form.is_valid()` method is called.
Expand All @@ -110,13 +113,21 @@ class BookForm(Form):
def clean_title(self):
if self.cleaned_data['title'] == "The Hitchhiker's Guide to the Galaxy":
self.add_error(('title', ), ValidationError("Too cool!", code='too-cool'))

if 'param' not in self.extras:
raise ValidationError("You can use extra optional arguments in form validation!")
return self.cleaned_data['title'].upper()

def clean(self):
if self.cleaned_data['title'] == "The Hitchhiker's Guide to the Galaxy" and self.cleaned_data['year'] < 1979:
# Non field validation errors are present under key `$body` in Form.errors property
raise ValidationError("Is it you Doctor?", code='time-travelling')

if 'param' not in self.extras:
self.add_error(
('param', ),
ValidationError("You can use extra optional arguments in form validation!", code='param-where')
)
# The last chance to do some touchy touchy with the self.clean_data

return self.cleaned_data
Expand Down
Loading

0 comments on commit 3aac8d2

Please sign in to comment.