or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

admin-integration.mdcountries-registry.mddjango-rest-framework.mdform-fields-widgets.mdgraphql-support.mdindex.mdmodel-fields.mdtemplate-tags.md

django-rest-framework.mddocs/

0

# Django REST Framework Integration

1

2

Serializer fields and mixins for Django REST Framework providing country serialization with flexible output formats. The integration supports code-only, name-only, and dictionary representations with automatic model field mapping.

3

4

## Capabilities

5

6

### CountryField Serializer

7

8

Specialized DRF serializer field for country data with flexible output formatting options.

9

10

```python { .api }

11

class CountryField(serializers.ChoiceField):

12

def __init__(

13

self,

14

*args,

15

country_dict=None,

16

name_only=None,

17

countries=None,

18

**kwargs

19

):

20

"""

21

DRF serializer field for country representation.

22

23

Parameters:

24

- country_dict: bool - Return country as {'code': 'US', 'name': 'United States'}

25

- name_only: bool - Return only country name instead of code

26

- countries: Countries - Custom countries instance

27

- **kwargs: Standard ChoiceField arguments

28

"""

29

30

def to_representation(self, obj):

31

"""

32

Convert country code to serialized representation.

33

34

Parameters:

35

- obj: Country code or Country object

36

37

Returns:

38

- Serialized country data based on field configuration

39

"""

40

41

def to_internal_value(self, data):

42

"""

43

Convert serialized data to country code.

44

45

Parameters:

46

- data: Serialized country data (code, name, or dict)

47

48

Returns:

49

- str: Country code for internal storage

50

"""

51

```

52

53

### Model Serializer Mixin

54

55

Automatic field mapping mixin for ModelSerializer classes that converts CountryField model fields to appropriate serializer fields.

56

57

```python { .api }

58

class CountryFieldMixin:

59

def build_standard_field(self, field_name, model_field):

60

"""

61

Build appropriate serializer field for CountryField model fields.

62

63

Parameters:

64

- field_name: str - Name of the field

65

- model_field: CountryField - Model field instance

66

67

Returns:

68

- Tuple[Field, dict]: Serializer field class and kwargs

69

"""

70

```

71

72

## Usage Examples

73

74

### Basic Serializer Usage

75

76

```python

77

from rest_framework import serializers

78

from django_countries.serializer_fields import CountryField

79

80

class PersonSerializer(serializers.Serializer):

81

name = serializers.CharField()

82

83

# Return country code only (default)

84

country = CountryField()

85

86

# Return country name only

87

birth_country = CountryField(name_only=True)

88

89

# Return country as dictionary with code and name

90

residence = CountryField(country_dict=True)

91

92

# Sample output:

93

# {

94

# "name": "John Doe",

95

# "country": "US",

96

# "birth_country": "United States",

97

# "residence": {"code": "US", "name": "United States"}

98

# }

99

```

100

101

### Model Serializer Integration

102

103

```python

104

from rest_framework import serializers

105

from django_countries.serializers import CountryFieldMixin

106

from myapp.models import Person

107

108

class PersonModelSerializer(CountryFieldMixin, serializers.ModelSerializer):

109

"""

110

ModelSerializer with automatic CountryField mapping.

111

CountryFieldMixin automatically converts model CountryFields to serializer CountryFields.

112

"""

113

class Meta:

114

model = Person

115

fields = ['name', 'country', 'visited_countries']

116

117

# Alternative manual configuration

118

class PersonCustomSerializer(serializers.ModelSerializer):

119

country = CountryField(country_dict=True)

120

visited_countries = serializers.ListField(

121

child=CountryField(name_only=True)

122

)

123

124

class Meta:

125

model = Person

126

fields = ['name', 'country', 'visited_countries']

127

```

128

129

### Custom Countries Instance

130

131

```python

132

from django_countries import Countries

133

from django_countries.serializer_fields import CountryField

134

135

# Create custom countries list

136

eu_countries = Countries()

137

eu_countries.only = ["DE", "FR", "IT", "ES", "NL", "BE"]

138

139

class EuropeanEventSerializer(serializers.Serializer):

140

title = serializers.CharField()

141

country = CountryField(countries=eu_countries)

142

```

143

144

## Input/Output Formats

145

146

### Input Format Handling

147

148

The CountryField accepts multiple input formats:

149

150

```python

151

# Valid input formats for CountryField:

152

153

# 1. Country code (alpha2, alpha3, numeric)

154

{"country": "US"}

155

{"country": "USA"}

156

{"country": "840"}

157

158

# 2. Country name (exact match)

159

{"country": "United States"}

160

161

# 3. Dictionary format

162

{"country": {"code": "US"}}

163

{"country": {"code": "US", "name": "United States"}}

164

```

165

166

### Output Format Options

167

168

```python

169

class FlexiblePersonSerializer(serializers.Serializer):

170

name = serializers.CharField()

171

172

# Code only (default): "US"

173

country_code = CountryField()

174

175

# Name only: "United States"

176

country_name = CountryField(name_only=True)

177

178

# Dictionary: {"code": "US", "name": "United States"}

179

country_full = CountryField(country_dict=True)

180

```

181

182

### Multiple Countries Handling

183

184

```python

185

from rest_framework import serializers

186

from django_countries.serializer_fields import CountryField

187

188

class OrganizationSerializer(serializers.ModelSerializer):

189

# Multiple countries as list of codes

190

operating_countries = serializers.ListField(

191

child=CountryField()

192

)

193

194

# Multiple countries as list of names

195

operating_regions = serializers.ListField(

196

child=CountryField(name_only=True)

197

)

198

199

# Multiple countries as list of dictionaries

200

detailed_countries = serializers.ListField(

201

child=CountryField(country_dict=True)

202

)

203

204

# Sample output:

205

# {

206

# "operating_countries": ["US", "CA", "MX"],

207

# "operating_regions": ["United States", "Canada", "Mexico"],

208

# "detailed_countries": [

209

# {"code": "US", "name": "United States"},

210

# {"code": "CA", "name": "Canada"},

211

# {"code": "MX", "name": "Mexico"}

212

# ]

213

# }

214

```

215

216

## Advanced Usage

217

218

### Validation and Error Handling

219

220

```python

221

class StrictCountrySerializer(serializers.Serializer):

222

country = CountryField()

223

224

def validate_country(self, value):

225

"""Custom country validation."""

226

if value not in ["US", "CA", "MX"]:

227

raise serializers.ValidationError(

228

"Only North American countries are allowed"

229

)

230

return value

231

232

# Invalid country codes raise ValidationError:

233

# serializer = StrictCountrySerializer(data={"country": "INVALID"})

234

# serializer.is_valid() # False

235

# serializer.errors # {"country": ["Select a valid choice..."]}

236

```

237

238

### ViewSet Integration

239

240

```python

241

from rest_framework import viewsets

242

from rest_framework.decorators import action

243

from rest_framework.response import Response

244

245

class PersonViewSet(viewsets.ModelViewSet):

246

serializer_class = PersonModelSerializer

247

248

@action(detail=False, methods=['get'])

249

def countries(self, request):

250

"""Return list of all available countries."""

251

from django_countries import countries

252

253

country_list = [

254

{"code": country.code, "name": country.name}

255

for country in countries

256

]

257

return Response(country_list)

258

259

@action(detail=False, methods=['get'])

260

def by_country(self, request):

261

"""Filter people by country."""

262

country_code = request.query_params.get('country')

263

if country_code:

264

queryset = self.get_queryset().filter(country=country_code)

265

serializer = self.get_serializer(queryset, many=True)

266

return Response(serializer.data)

267

return Response([])

268

```

269

270

### Custom Field Behavior

271

272

```python

273

class ExtendedCountryField(CountryField):

274

"""Custom country field with additional metadata."""

275

276

def to_representation(self, obj):

277

"""Add additional country metadata."""

278

from django_countries import countries

279

280

code = countries.alpha2(obj)

281

if not code:

282

return ""

283

284

return {

285

"code": code,

286

"name": countries.name(code),

287

"alpha3": countries.alpha3(code),

288

"numeric": countries.numeric(code),

289

"flag_url": f"/static/flags/{code.lower()}.gif"

290

}

291

292

class DetailedPersonSerializer(serializers.Serializer):

293

name = serializers.CharField()

294

country = ExtendedCountryField()

295

296

# Output:

297

# {

298

# "name": "John Doe",

299

# "country": {

300

# "code": "US",

301

# "name": "United States",

302

# "alpha3": "USA",

303

# "numeric": 840,

304

# "flag_url": "/static/flags/us.gif"

305

# }

306

# }

307

```

308

309

### Filtering and Search

310

311

```python

312

from django_filter import rest_framework as filters

313

314

class PersonFilter(filters.FilterSet):

315

country = filters.CharFilter(field_name='country')

316

country_name = filters.CharFilter(

317

field_name='country',

318

lookup_expr='name_icontains'

319

)

320

321

class Meta:

322

model = Person

323

fields = ['country', 'country_name']

324

325

class PersonViewSet(viewsets.ModelViewSet):

326

serializer_class = PersonModelSerializer

327

filterset_class = PersonFilter

328

329

# URL examples:

330

# /api/people/?country=US

331

# /api/people/?country_name=united

332

```

333

334

## Integration Patterns

335

336

### API Versioning

337

338

```python

339

class PersonV1Serializer(serializers.ModelSerializer):

340

"""v1 API returns country codes only."""

341

country = CountryField()

342

343

class Meta:

344

model = Person

345

fields = ['name', 'country']

346

347

class PersonV2Serializer(serializers.ModelSerializer):

348

"""v2 API returns country with full details."""

349

country = CountryField(country_dict=True)

350

351

class Meta:

352

model = Person

353

fields = ['name', 'country']

354

```

355

356

### Nested Serialization

357

358

```python

359

class AddressSerializer(serializers.Serializer):

360

street = serializers.CharField()

361

city = serializers.CharField()

362

country = CountryField(country_dict=True)

363

364

class PersonWithAddressSerializer(serializers.Serializer):

365

name = serializers.CharField()

366

address = AddressSerializer()

367

368

# Output:

369

# {

370

# "name": "John Doe",

371

# "address": {

372

# "street": "123 Main St",

373

# "city": "New York",

374

# "country": {"code": "US", "name": "United States"}

375

# }

376

# }

377

```

378

379

### Performance Optimization

380

381

```python

382

class OptimizedPersonSerializer(serializers.ModelSerializer):

383

"""Optimized serializer for bulk operations."""

384

385

# Use code-only for better performance in lists

386

country = CountryField()

387

388

def to_representation(self, instance):

389

"""Add country name only when needed."""

390

data = super().to_representation(instance)

391

392

# Add country name for detail views

393

if self.context.get('detail_view'):

394

from django_countries import countries

395

data['country_name'] = countries.name(data['country'])

396

397

return data

398

```