or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

appengine-integration.mdcore-admin.mdfile-admin.mdforms.mdgeoalchemy-integration.mdhelpers-utilities.mdindex.mdmodel-views.mdmongoengine-integration.mdredis-integration.mdsqlalchemy-integration.md

mongoengine-integration.mddocs/

0

# MongoEngine Integration

1

2

MongoDB document administration through MongoEngine ORM integration with embedded documents, NoSQL-specific features, and flexible document structures.

3

4

## Capabilities

5

6

### MongoEngine Model View

7

8

Main model view class for MongoEngine documents with CRUD operations, embedded document handling, and MongoDB-specific querying.

9

10

```python { .api }

11

from flask_admin.contrib.mongoengine import ModelView

12

13

class ModelView(BaseModelView):

14

def __init__(self, model, name=None, category=None, endpoint=None, url=None, **kwargs):

15

"""

16

Initialize MongoEngine model view.

17

18

Args:

19

model: MongoEngine document class

20

name (str, optional): View name for menu

21

category (str, optional): Menu category

22

endpoint (str, optional): Blueprint endpoint

23

url (str, optional): URL prefix

24

**kwargs: Additional view configuration

25

"""

26

27

# MongoEngine-specific configuration

28

subdocuments = {} # Embedded document configuration

29

embedded_list_columns = [] # Columns for embedded lists

30

31

# MongoDB querying

32

def get_query(self):

33

"""

34

Get base QuerySet for list view.

35

36

Returns:

37

QuerySet: MongoEngine QuerySet object

38

"""

39

40

def get_list(self, page, sort_column, sort_desc, search, filters, execute=True, page_size=None):

41

"""

42

Get paginated document list with sorting, searching, and filtering.

43

44

Args:

45

page (int): Page number (0-based)

46

sort_column (str): Field to sort by

47

sort_desc (bool): Sort in descending order

48

search (str): Search query string

49

filters (list): Active filter list

50

execute (bool): Execute query immediately

51

page_size (int, optional): Items per page

52

53

Returns:

54

tuple: (total_count, items) if execute=True, queryset if execute=False

55

"""

56

57

def get_one(self, id):

58

"""

59

Get single document instance by ObjectId.

60

61

Args:

62

id (str): Document ObjectId as string

63

64

Returns:

65

Document instance or None if not found

66

"""

67

68

# CRUD operations for documents

69

def create_model(self, form):

70

"""

71

Create new document instance from form data.

72

73

Args:

74

form: Validated form instance

75

76

Returns:

77

bool: True if creation successful

78

"""

79

80

def update_model(self, form, model):

81

"""

82

Update existing document instance from form data.

83

84

Args:

85

form: Validated form instance

86

model: Document instance to update

87

88

Returns:

89

bool: True if update successful

90

"""

91

92

def delete_model(self, model):

93

"""

94

Delete document instance.

95

96

Args:

97

model: Document instance to delete

98

99

Returns:

100

bool: True if deletion successful

101

"""

102

103

# Form scaffolding for MongoEngine

104

def scaffold_form(self):

105

"""

106

Auto-generate form class from MongoEngine document.

107

108

Returns:

109

Form class with fields for document fields

110

"""

111

112

def scaffold_list_form(self, widget=None, validators=None):

113

"""

114

Generate form for inline list editing.

115

116

Args:

117

widget: Custom widget for fields

118

validators: Custom validators

119

120

Returns:

121

Form class for inline editing

122

"""

123

124

def scaffold_filters(self, name):

125

"""

126

Generate filters for document field.

127

128

Args:

129

name (str): Field name

130

131

Returns:

132

list: Available filter types for field

133

"""

134

135

# MongoDB-specific methods

136

def get_pk_value(self, model):

137

"""

138

Get primary key (ObjectId) from document instance.

139

140

Args:

141

model: Document instance

142

143

Returns:

144

str: ObjectId as string

145

"""

146

147

def apply_search(self, query, search):

148

"""

149

Apply text search filters to QuerySet.

150

151

Args:

152

query: Base QuerySet

153

search (str): Search string

154

155

Returns:

156

QuerySet: QuerySet with search filters applied

157

"""

158

159

def apply_filters(self, query, filters):

160

"""

161

Apply field filters to QuerySet.

162

163

Args:

164

query: Base QuerySet

165

filters (list): Active filters

166

167

Returns:

168

QuerySet: QuerySet with filters applied

169

"""

170

171

def apply_sorting(self, query, sort_field, sort_desc):

172

"""

173

Apply sorting to QuerySet.

174

175

Args:

176

query: Base QuerySet

177

sort_field (str): Field to sort by

178

sort_desc (bool): Sort descending

179

180

Returns:

181

QuerySet: Sorted QuerySet

182

"""

183

```

184

185

### Embedded Document Forms

186

187

Support for editing embedded documents within parent document forms.

188

189

```python { .api }

190

class EmbeddedForm:

191

def __init__(

192

self,

193

form_base_class=None,

194

form_columns=None,

195

excluded_form_columns=None,

196

form_args=None,

197

form_widget_args=None,

198

form_overrides=None

199

):

200

"""

201

Initialize embedded document form configuration.

202

203

Args:

204

form_base_class: Base form class for embedded form

205

form_columns (list, optional): Fields to include in embedded form

206

excluded_form_columns (list, optional): Fields to exclude

207

form_args (dict, optional): Form field arguments

208

form_widget_args (dict, optional): Widget arguments

209

form_overrides (dict, optional): Field type overrides

210

"""

211

```

212

213

## Usage Examples

214

215

### Basic MongoEngine Model View

216

217

```python

218

from flask import Flask

219

from flask_mongoengine import MongoEngine

220

from flask_admin import Admin

221

from flask_admin.contrib.mongoengine import ModelView

222

from mongoengine import Document, EmbeddedDocument, fields

223

from datetime import datetime

224

225

app = Flask(__name__)

226

app.config['MONGODB_SETTINGS'] = {

227

'db': 'blog',

228

'host': 'localhost',

229

'port': 27017

230

}

231

app.config['SECRET_KEY'] = 'secret-key'

232

233

db = MongoEngine(app)

234

235

# Define documents

236

class User(Document):

237

username = fields.StringField(max_length=80, unique=True, required=True)

238

email = fields.EmailField(required=True)

239

created_at = fields.DateTimeField(default=datetime.utcnow)

240

is_active = fields.BooleanField(default=True)

241

profile = fields.EmbeddedDocumentField('UserProfile')

242

243

class UserProfile(EmbeddedDocument):

244

first_name = fields.StringField(max_length=50)

245

last_name = fields.StringField(max_length=50)

246

bio = fields.StringField(max_length=500)

247

avatar_url = fields.URLField()

248

249

class BlogPost(Document):

250

title = fields.StringField(max_length=200, required=True)

251

content = fields.StringField()

252

author = fields.ReferenceField(User, required=True)

253

tags = fields.ListField(fields.StringField(max_length=50))

254

created_at = fields.DateTimeField(default=datetime.utcnow)

255

published = fields.BooleanField(default=False)

256

257

meta = {

258

'indexes': ['title', 'author', 'created_at'],

259

'ordering': ['-created_at']

260

}

261

262

# Create admin views

263

class UserModelView(ModelView):

264

list_columns = ['username', 'email', 'profile.first_name', 'profile.last_name', 'created_at', 'is_active']

265

column_searchable_list = ['username', 'email', 'profile.first_name', 'profile.last_name']

266

column_filters = ['is_active', 'created_at']

267

268

form_subdocuments = {

269

'profile': {

270

'form_columns': ['first_name', 'last_name', 'bio', 'avatar_url']

271

}

272

}

273

274

class BlogPostModelView(ModelView):

275

list_columns = ['title', 'author.username', 'created_at', 'published']

276

column_searchable_list = ['title', 'content', 'author.username']

277

column_filters = ['author', 'published', 'created_at', 'tags']

278

279

form_columns = ['title', 'content', 'author', 'tags', 'published']

280

281

# Initialize admin

282

admin = Admin(app, name='Blog Admin')

283

admin.add_view(UserModelView(User, name='Users'))

284

admin.add_view(BlogPostModelView(BlogPost, name='Blog Posts'))

285

```

286

287

### Embedded Document Handling

288

289

```python

290

from flask_admin.contrib.mongoengine import EmbeddedForm

291

292

class Address(EmbeddedDocument):

293

street = fields.StringField(max_length=200)

294

city = fields.StringField(max_length=100)

295

state = fields.StringField(max_length=50)

296

zip_code = fields.StringField(max_length=20)

297

country = fields.StringField(max_length=50, default='USA')

298

299

class ContactInfo(EmbeddedDocument):

300

phone = fields.StringField(max_length=20)

301

fax = fields.StringField(max_length=20)

302

website = fields.URLField()

303

304

class Company(Document):

305

name = fields.StringField(max_length=200, required=True)

306

address = fields.EmbeddedDocumentField(Address)

307

contact = fields.EmbeddedDocumentField(ContactInfo)

308

employees = fields.ListField(fields.ReferenceField(User))

309

founded = fields.DateTimeField()

310

311

class CompanyModelView(ModelView):

312

# Configure embedded document forms

313

form_subdocuments = {

314

'address': {

315

'form_columns': ['street', 'city', 'state', 'zip_code', 'country'],

316

'form_args': {

317

'country': {'default': 'USA'}

318

}

319

},

320

'contact': {

321

'form_columns': ['phone', 'website'], # Exclude fax

322

'form_widget_args': {

323

'phone': {'placeholder': '+1-555-123-4567'},

324

'website': {'placeholder': 'https://example.com'}

325

}

326

}

327

}

328

329

# Display embedded fields in list

330

list_columns = ['name', 'address.city', 'address.state', 'contact.phone', 'founded']

331

332

column_labels = {

333

'address.city': 'City',

334

'address.state': 'State',

335

'contact.phone': 'Phone'

336

}

337

338

admin.add_view(CompanyModelView(Company, name='Companies'))

339

```

340

341

### Advanced MongoDB Queries and Filtering

342

343

```python

344

from mongoengine import Q

345

from flask_admin.contrib.mongoengine.filters import FilterEqual, FilterLike, FilterInList

346

347

class AdvancedBlogPostView(ModelView):

348

# Text search across multiple fields

349

column_searchable_list = ['title', 'content', 'tags']

350

351

# MongoDB-specific filters

352

column_filters = [

353

'author',

354

'published',

355

'created_at',

356

FilterLike('title', 'Title Contains'),

357

FilterEqual('author', 'Exact Author'),

358

FilterInList('tags', 'Has Tags', options=[

359

('python', 'Python'),

360

('flask', 'Flask'),

361

('mongodb', 'MongoDB')

362

])

363

]

364

365

# Custom query with MongoDB aggregation

366

def get_query(self):

367

# Add complex filters using MongoEngine Q objects

368

return BlogPost.objects.filter(

369

Q(published=True) | Q(author=current_user.id)

370

)

371

372

# Custom search with regex

373

def apply_search(self, query, search):

374

if search:

375

# MongoDB regex search (case-insensitive)

376

search_filter = (

377

Q(title__icontains=search) |

378

Q(content__icontains=search) |

379

Q(tags__in=[search])

380

)

381

query = query.filter(search_filter)

382

return query

383

384

# Custom column formatter for tags

385

def _tags_formatter(view, context, model, name):

386

if model.tags:

387

return ', '.join(model.tags[:3]) # Show first 3 tags

388

return ''

389

390

column_formatters = {

391

'tags': _tags_formatter

392

}

393

```

394

395

### List and Embedded List Fields

396

397

```python

398

class Product(EmbeddedDocument):

399

name = fields.StringField(required=True)

400

price = fields.DecimalField(min_value=0)

401

sku = fields.StringField()

402

403

class Order(Document):

404

order_number = fields.StringField(unique=True, required=True)

405

customer_email = fields.EmailField(required=True)

406

products = fields.ListField(fields.EmbeddedDocumentField(Product))

407

shipping_address = fields.EmbeddedDocumentField(Address)

408

order_date = fields.DateTimeField(default=datetime.utcnow)

409

status = fields.StringField(

410

choices=['pending', 'processing', 'shipped', 'delivered'],

411

default='pending'

412

)

413

414

class OrderModelView(ModelView):

415

# Configure embedded list editing

416

form_subdocuments = {

417

'products': {

418

'form_columns': ['name', 'price', 'sku'],

419

'form_widget_args': {

420

'price': {'step': '0.01', 'min': '0'}

421

}

422

},

423

'shipping_address': {

424

'form_columns': ['street', 'city', 'state', 'zip_code']

425

}

426

}

427

428

list_columns = [

429

'order_number',

430

'customer_email',

431

'products_count',

432

'order_date',

433

'status'

434

]

435

436

# Custom formatter for product count

437

def _products_count_formatter(view, context, model, name):

438

return len(model.products) if model.products else 0

439

440

column_formatters = {

441

'products_count': _products_count_formatter

442

}

443

444

column_labels = {

445

'products_count': 'Items'

446

}

447

448

# Custom form processing

449

def on_model_change(self, form, model, is_created):

450

# Generate order number for new orders

451

if is_created and not model.order_number:

452

import uuid

453

model.order_number = f'ORD-{uuid.uuid4().hex[:8].upper()}'

454

```

455

456

### File Upload with GridFS

457

458

```python

459

from mongoengine import FileField

460

from werkzeug.utils import secure_filename

461

462

class Document(Document):

463

title = fields.StringField(required=True)

464

description = fields.StringField()

465

file = FileField()

466

uploaded_at = fields.DateTimeField(default=datetime.utcnow)

467

uploaded_by = fields.ReferenceField(User)

468

469

class DocumentModelView(ModelView):

470

form_columns = ['title', 'description', 'file']

471

list_columns = ['title', 'file.filename', 'uploaded_at', 'uploaded_by.username']

472

473

column_labels = {

474

'file.filename': 'Filename',

475

'uploaded_by.username': 'Uploaded By'

476

}

477

478

# Custom file formatter

479

def _file_formatter(view, context, model, name):

480

if model.file:

481

return Markup(f'<a href="/download/{model.id}">{model.file.filename}</a>')

482

return ''

483

484

column_formatters = {

485

'file': _file_formatter

486

}

487

488

def on_model_change(self, form, model, is_created):

489

# Set uploaded_by to current user

490

if is_created:

491

model.uploaded_by = current_user._get_current_object()

492

```

493

494

### Custom Actions for MongoDB

495

496

```python

497

from flask_admin.actions import action

498

from flask import flash

499

500

class UserModelView(ModelView):

501

@action('activate', 'Activate Users', 'Activate selected users?')

502

def action_activate(self, ids):

503

try:

504

# Bulk update using MongoEngine

505

count = User.objects(id__in=ids).update(set__is_active=True)

506

flash(f'Successfully activated {count} users.', 'success')

507

except Exception as ex:

508

flash(f'Failed to activate users: {str(ex)}', 'error')

509

510

@action('send_email', 'Send Welcome Email')

511

def action_send_email(self, ids):

512

try:

513

users = User.objects(id__in=ids)

514

for user in users:

515

# Send email logic here

516

send_welcome_email(user.email)

517

flash(f'Sent emails to {len(users)} users.', 'success')

518

except Exception as ex:

519

flash(f'Failed to send emails: {str(ex)}', 'error')

520

```