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

admin-integration.mddocs/

0

# Admin Integration

1

2

Django admin integration with optimized country filters and form field handling. The admin integration provides efficient country-based filtering and selection in the Django admin interface with automatic field handling.

3

4

## Capabilities

5

6

### CountryFilter

7

8

Optimized Django admin list filter that only shows countries present in the current queryset, improving performance and user experience.

9

10

```python { .api }

11

class CountryFilter(admin.FieldListFilter):

12

"""

13

Optimized country filter for Django admin.

14

Only shows countries that exist in the current queryset.

15

"""

16

17

title = "Country" # Filter title in admin

18

19

def expected_parameters(self):

20

"""Return expected URL parameters for this filter."""

21

22

def choices(self, changelist):

23

"""Generate filter choice options."""

24

25

def lookup_choices(self, changelist):

26

"""Get available country choices from current queryset."""

27

```

28

29

## Usage Examples

30

31

### Basic Admin Configuration

32

33

```python

34

from django.contrib import admin

35

from django_countries.filters import CountryFilter

36

from myapp.models import Person

37

38

@admin.register(Person)

39

class PersonAdmin(admin.ModelAdmin):

40

list_display = ['name', 'country', 'email']

41

list_filter = [

42

('country', CountryFilter), # Use optimized country filter

43

'created_date'

44

]

45

search_fields = ['name', 'email']

46

47

# CountryField automatically gets proper admin widget

48

# No additional field configuration needed

49

```

50

51

### Multiple Country Fields

52

53

```python

54

from django.contrib import admin

55

from django_countries.filters import CountryFilter

56

from myapp.models import Organization

57

58

@admin.register(Organization)

59

class OrganizationAdmin(admin.ModelAdmin):

60

list_display = ['name', 'headquarters_country', 'employee_count']

61

list_filter = [

62

('headquarters_country', CountryFilter),

63

('operating_countries', CountryFilter), # Works with multiple countries too

64

'organization_type'

65

]

66

67

fieldsets = (

68

('Basic Information', {

69

'fields': ('name', 'description')

70

}),

71

('Geographic Information', {

72

'fields': ('headquarters_country', 'operating_countries')

73

}),

74

)

75

```

76

77

### Custom Admin Configuration

78

79

```python

80

from django.contrib import admin

81

from django import forms

82

from django_countries.widgets import CountrySelectWidget

83

from django_countries.filters import CountryFilter

84

from myapp.models import Event

85

86

class EventAdminForm(forms.ModelForm):

87

"""Custom admin form with enhanced country widget."""

88

89

class Meta:

90

model = Event

91

fields = '__all__'

92

widgets = {

93

'country': CountrySelectWidget(attrs={

94

'class': 'admin-country-select',

95

'style': 'width: 200px;'

96

})

97

}

98

99

@admin.register(Event)

100

class EventAdmin(admin.ModelAdmin):

101

form = EventAdminForm

102

list_display = ['title', 'country', 'start_date', 'attendee_count']

103

list_filter = [

104

('country', CountryFilter),

105

'event_type',

106

'start_date'

107

]

108

109

# Enable country-based search

110

search_fields = ['title', 'description', 'country__name_exact']

111

```

112

113

### Inline Admin Support

114

115

```python

116

from django.contrib import admin

117

from myapp.models import Company, Office

118

119

class OfficeInline(admin.TabularInline):

120

"""Inline for company offices with country selection."""

121

model = Office

122

extra = 1

123

fields = ['city', 'country', 'employee_count']

124

125

# CountryField automatically gets proper inline widget

126

127

@admin.register(Company)

128

class CompanyAdmin(admin.ModelAdmin):

129

list_display = ['name', 'headquarters_country', 'total_offices']

130

list_filter = [

131

('headquarters_country', CountryFilter),

132

]

133

inlines = [OfficeInline]

134

135

def total_offices(self, obj):

136

return obj.offices.count()

137

total_offices.short_description = 'Total Offices'

138

```

139

140

## Filter Behavior

141

142

### Optimized Filtering

143

144

The CountryFilter only displays countries that exist in the current queryset:

145

146

```python

147

# Example: Person model with countries ["US", "CA", "DE", "FR", "JP"]

148

# CountryFilter will only show these 5 countries as options

149

# Instead of showing all 249+ countries

150

151

@admin.register(Person)

152

class PersonAdmin(admin.ModelAdmin):

153

list_filter = [('country', CountryFilter)]

154

155

# Filter automatically adapts to:

156

# - Current search results

157

# - Other active filters

158

# - Queryset restrictions

159

```

160

161

### Filter URL Parameters

162

163

```python

164

# CountryFilter generates clean URL parameters:

165

# /admin/myapp/person/?country=US

166

# /admin/myapp/person/?country=US&country=CA (multiple selection in Django 5.0+)

167

168

# Works with other filters:

169

# /admin/myapp/person/?country=US&created_date__gte=2023-01-01

170

```

171

172

### Multiple Country Field Filtering

173

174

```python

175

from myapp.models import Organization

176

177

@admin.register(Organization)

178

class OrganizationAdmin(admin.ModelAdmin):

179

list_filter = [

180

('headquarters_country', CountryFilter),

181

('operating_countries', CountryFilter), # Filters multiple country field

182

]

183

184

# operating_countries filter shows all countries that appear

185

# in ANY organization's operating_countries list

186

```

187

188

## Advanced Admin Features

189

190

### Custom Filter Labels

191

192

```python

193

from django_countries.filters import CountryFilter

194

195

class HeadquartersCountryFilter(CountryFilter):

196

title = 'Headquarters Location' # Custom filter title

197

198

class OperatingRegionFilter(CountryFilter):

199

title = 'Operating Regions'

200

201

@admin.register(Organization)

202

class OrganizationAdmin(admin.ModelAdmin):

203

list_filter = [

204

('headquarters_country', HeadquartersCountryFilter),

205

('operating_countries', OperatingRegionFilter),

206

]

207

```

208

209

### Custom Country Display

210

211

```python

212

from django.contrib import admin

213

from django_countries import countries

214

215

@admin.register(Person)

216

class PersonAdmin(admin.ModelAdmin):

217

list_display = ['name', 'get_country_display', 'email']

218

list_filter = [('country', CountryFilter)]

219

220

def get_country_display(self, obj):

221

"""Custom country display with flag."""

222

if obj.country:

223

flag_url = obj.country.flag

224

return format_html(

225

'<img src="{}" width="16" height="12" style="margin-right: 5px;"> {}',

226

flag_url,

227

obj.country.name

228

)

229

return '-'

230

get_country_display.short_description = 'Country'

231

get_country_display.admin_order_field = 'country'

232

```

233

234

### Bulk Actions with Countries

235

236

```python

237

from django.contrib import admin

238

from django.contrib import messages

239

240

@admin.register(Person)

241

class PersonAdmin(admin.ModelAdmin):

242

list_display = ['name', 'country', 'status']

243

list_filter = [('country', CountryFilter)]

244

actions = ['assign_to_us_region', 'export_by_country']

245

246

def assign_to_us_region(self, request, queryset):

247

"""Bulk assign people to US region."""

248

count = queryset.filter(country='US').update(region='North America')

249

messages.success(request, f'Updated {count} US residents to North America region.')

250

assign_to_us_region.short_description = 'Update US residents region'

251

252

def export_by_country(self, request, queryset):

253

"""Export selected records grouped by country."""

254

countries_data = {}

255

for person in queryset:

256

country = person.country.name if person.country else 'Unknown'

257

if country not in countries_data:

258

countries_data[country] = []

259

countries_data[country].append(person)

260

261

# Generate export (simplified example)

262

messages.info(request, f'Export prepared for {len(countries_data)} countries.')

263

export_by_country.short_description = 'Export by country'

264

```

265

266

### ReadOnly Country Display

267

268

```python

269

from django.contrib import admin

270

from django.utils.html import format_html

271

272

@admin.register(Person)

273

class PersonAdmin(admin.ModelAdmin):

274

list_display = ['name', 'country_with_flag']

275

readonly_fields = ['country_details']

276

277

def country_with_flag(self, obj):

278

"""Display country with flag in list view."""

279

if obj.country:

280

return format_html(

281

'<img src="{}" width="20"> {} ({})',

282

obj.country.flag,

283

obj.country.name,

284

obj.country.code

285

)

286

return '-'

287

country_with_flag.short_description = 'Country'

288

289

def country_details(self, obj):

290

"""Detailed country info in form view."""

291

if obj.country:

292

return format_html(

293

'''

294

<div style="padding: 10px; border: 1px solid #ddd;">

295

<img src="{}" width="32" style="float: left; margin-right: 10px;">

296

<strong>{}</strong><br>

297

Code: {}<br>

298

Alpha3: {}<br>

299

Numeric: {}<br>

300

IOC: {}

301

</div>

302

''',

303

obj.country.flag,

304

obj.country.name,

305

obj.country.code,

306

obj.country.alpha3,

307

obj.country.numeric or 'N/A',

308

obj.country.ioc_code or 'N/A'

309

)

310

return 'No country selected'

311

country_details.short_description = 'Country Information'

312

```

313

314

### Custom Fieldsets

315

316

```python

317

@admin.register(Organization)

318

class OrganizationAdmin(admin.ModelAdmin):

319

fieldsets = (

320

('Basic Information', {

321

'fields': ('name', 'description', 'website')

322

}),

323

('Location & Operations', {

324

'fields': ('headquarters_country', 'operating_countries'),

325

'description': 'Specify headquarters location and all countries of operation.'

326

}),

327

('Contact Information', {

328

'fields': ('contact_email', 'phone'),

329

'classes': ('collapse',)

330

}),

331

)

332

333

list_filter = [

334

('headquarters_country', CountryFilter),

335

('operating_countries', CountryFilter),

336

]

337

```

338

339

### Admin Search Integration

340

341

```python

342

@admin.register(Person)

343

class PersonAdmin(admin.ModelAdmin):

344

search_fields = [

345

'name',

346

'email',

347

'country__name_icontains', # Search by country name

348

]

349

list_filter = [('country', CountryFilter)]

350

351

# Example searches:

352

# "john" - finds people named John

353

# "united" - finds people from countries containing "United"

354

# "us" - finds people from countries containing "us" (like "United States", "Russia")

355

```

356

357

### Performance Optimization

358

359

```python

360

from django.contrib import admin

361

from django.db import models

362

363

@admin.register(Person)

364

class PersonAdmin(admin.ModelAdmin):

365

list_display = ['name', 'get_country_name']

366

list_filter = [('country', CountryFilter)]

367

368

# Optimize queries

369

def get_queryset(self, request):

370

"""Optimize queryset for country access."""

371

qs = super().get_queryset(request)

372

# CountryField doesn't need select_related since it's not a ForeignKey

373

# Country objects are created on-demand from stored codes

374

return qs

375

376

def get_country_name(self, obj):

377

"""Efficient country name display."""

378

return obj.country.name if obj.country else '-'

379

get_country_name.short_description = 'Country'

380

get_country_name.admin_order_field = 'country' # Enable sorting

381

```