Skip to content

Commit c1bfb8b

Browse files
authored
Fixed calling population methods when declared in form (#66)
1 parent 4522681 commit c1bfb8b

File tree

6 files changed

+62
-4
lines changed

6 files changed

+62
-4
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
## 1.0.0-rc.10 : 02.08.2024
4+
5+
- **Fixed**: Fixed calling population methods when declared in form
6+
37
## 1.0.0-rc.9 : 24.03.2023
48

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

LICENSE

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2020 Jakub Dubec
3+
Copyright (c) 2024 Jakub Dubec
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

django_api_forms/forms.py

+4
Original file line numberDiff line numberDiff line change
@@ -186,13 +186,17 @@ def populate(self, obj, exclude: List[str] = None):
186186
field_class, "django_api_forms.population_strategies.BaseStrategy"
187187
)
188188
)
189+
189190
if isinstance(self.Meta, type):
190191
if hasattr(self.Meta, 'field_strategy'):
191192
if key in self.Meta.field_strategy.keys():
192193
strategy = resolve_from_path(
193194
self.Meta.field_strategy[key]
194195
)
195196

197+
if hasattr(self, f'populate_{key}'):
198+
self.cleaned_data[key] = getattr(self, f'populate_{key}')(obj, self.cleaned_data[key])
199+
196200
strategy()(field, obj, key, self.cleaned_data[key])
197201

198202
return obj

django_api_forms/version.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = '1.0.0-rc.9'
1+
__version__ = '1.0.0-rc.10'

pyproject.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "django-api-forms"
3-
version = "1.0.0-rc.9"
3+
version = "1.0.0-rc.10"
44
description = "Declarative Django request validation for RESTful APIs"
55
authors = [
66
"Jakub Dubec <[email protected]>",

tests/test_population.py

+51-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1+
from django.forms import fields
12
from django.test import TestCase
23
from django.test.client import RequestFactory
34

5+
from django_api_forms import Form, EnumField, FormField
46
from django_api_forms.exceptions import ApiFormException
57
from tests import settings
6-
from tests.testapp.forms import AlbumForm, BandForm
8+
from tests.testapp.forms import AlbumForm, BandForm, ArtistForm
79
from tests.testapp.models import Album, Artist, Band
810

911

@@ -73,3 +75,51 @@ def test_invalid_populate(self):
7375
album = Album()
7476
with self.assertRaisesMessage(ApiFormException, str('No clean data provided! Try to call is_valid() first.')):
7577
form.populate(album)
78+
79+
def test_form_method_populate(self):
80+
class MyAlbumForm(Form):
81+
title = fields.CharField(max_length=100)
82+
year = fields.IntegerField()
83+
artist = FormField(form=ArtistForm)
84+
type = EnumField(enum=Album.AlbumType, required=True)
85+
86+
def populate_year(self, obj, value: int) -> int:
87+
return 2020
88+
89+
def populate_artist(self, obj, value: dict) -> Artist:
90+
artist = Artist()
91+
92+
artist.name = value['name']
93+
artist.genres = value['genres']
94+
artist.members = value['members']
95+
96+
obj.artist = artist
97+
98+
return artist
99+
100+
request_factory = RequestFactory()
101+
data = {
102+
'title': 'Unknown Pleasures',
103+
'year': 1979,
104+
'artist': {
105+
"name": "Punk Pineapples",
106+
"genres": ["Punk", "Tropical Rock"],
107+
"members": 5
108+
},
109+
'type': 'vinyl'
110+
}
111+
112+
request = request_factory.post(
113+
'/test/',
114+
data=data,
115+
content_type='application/json'
116+
)
117+
118+
my_model = Album()
119+
form = MyAlbumForm.create_from_request(request)
120+
self.assertTrue(form.is_valid())
121+
122+
form.populate(my_model)
123+
self.assertIsInstance(my_model.artist, Artist)
124+
self.assertEqual(my_model.year, 2020)
125+
self.assertEqual(my_model.artist.name, 'Punk Pineapples')

0 commit comments

Comments
 (0)