or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

access-control.mdajax-json.mdform-processing.mdhttp-utilities.mdindex.mdquery-optimization.md

form-processing.mddocs/

0

# Form Processing and Messaging

1

2

Mixins for enhanced form processing, validation messaging, CSRF handling, and context injection. These mixins solve common form-related challenges in Django class-based views and provide consistent user feedback patterns.

3

4

## Capabilities

5

6

### CSRF Exemption

7

8

Exempt views from CSRF protection for API endpoints and special cases.

9

10

```python { .api }

11

class CsrfExemptMixin:

12

"""Exempts the view from CSRF requirements"""

13

14

@method_decorator(csrf_exempt)

15

def dispatch(self, *args, **kwargs):

16

"""Dispatch with CSRF exemption applied"""

17

```

18

19

Usage example:

20

21

```python

22

from django.views.generic import CreateView

23

from braces.views import CsrfExemptMixin, JsonRequestResponseMixin

24

25

class APICreateView(CsrfExemptMixin, JsonRequestResponseMixin, CreateView):

26

model = MyModel

27

28

def post(self, request, *args, **kwargs):

29

# Process JSON data without CSRF token

30

data = self.request_json

31

# Create object...

32

return self.render_json_response({'status': 'created'})

33

```

34

35

**Note**: CsrfExemptMixin should be the leftmost mixin in inheritance chain.

36

37

### User Context Injection

38

39

Automatically pass the current user to form initialization.

40

41

```python { .api }

42

class UserFormKwargsMixin:

43

"""Automatically include request.user in form kwargs"""

44

45

def get_form_kwargs(self):

46

"""Update form kwargs with current user"""

47

```

48

49

Usage example:

50

51

```python

52

from django.views.generic import CreateView

53

from braces.views import UserFormKwargsMixin

54

55

class UserAwareCreateView(UserFormKwargsMixin, CreateView):

56

model = MyModel

57

form_class = MyModelForm

58

59

# Form will receive user in __init__

60

```

61

62

Form implementation:

63

64

```python

65

from django import forms

66

67

class MyModelForm(forms.ModelForm):

68

def __init__(self, *args, **kwargs):

69

self.user = kwargs.pop('user', None) # Extract user from kwargs

70

super().__init__(*args, **kwargs)

71

72

# Use self.user for field customization

73

if self.user and not self.user.is_staff:

74

del self.fields['admin_notes']

75

76

class Meta:

77

model = MyModel

78

fields = '__all__'

79

```

80

81

### Standalone Form Mixins

82

83

For direct use in form classes (imported from `braces.forms`):

84

85

```python { .api }

86

class UserKwargModelFormMixin:

87

"""Form mixin for popping user out of kwargs and attaching to instance"""

88

user = None

89

90

def __init__(self, *args, **kwargs):

91

"""Remove user from kwargs and assign to self.user"""

92

```

93

94

Usage example:

95

96

```python

97

from django import forms

98

from braces.forms import UserKwargModelFormMixin

99

100

class MyModelForm(UserKwargModelFormMixin, forms.ModelForm):

101

def __init__(self, *args, **kwargs):

102

super().__init__(*args, **kwargs) # Automatically extracts user

103

104

# Now self.user is available for customization

105

if self.user and not self.user.is_staff:

106

del self.fields['admin_notes']

107

108

class Meta:

109

model = MyModel

110

fields = '__all__'

111

112

# Usage in view

113

class MyCreateView(UserFormKwargsMixin, CreateView):

114

model = MyModel

115

form_class = MyModelForm # Form will receive user automatically

116

```

117

118

### Success URL Handling

119

120

Automatic success URL generation from named URL patterns.

121

122

```python { .api }

123

class SuccessURLRedirectListMixin:

124

"""Automatically reverse success_list_url as success_url"""

125

success_list_url = None

126

127

def get_success_url(self):

128

"""Return reversed success url"""

129

```

130

131

Usage example:

132

133

```python

134

from django.views.generic import CreateView

135

from braces.views import SuccessURLRedirectListMixin

136

137

class CreateItemView(SuccessURLRedirectListMixin, CreateView):

138

model = Item

139

success_list_url = 'item:list' # URL name to redirect to after success

140

```

141

142

### Form Validation Messages

143

144

Consistent success and error messaging for form processing.

145

146

```python { .api }

147

class MessageMixin:

148

"""Add messages attribute for Django's messages framework"""

149

# Provides self.messages with methods: add_message, debug, info, success, warning, error

150

151

def __init__(self, *args, **kwargs):

152

"""Initialize with class name reference"""

153

154

class FormValidMessageMixin(MessageMixin):

155

"""Set message when form passes validation"""

156

form_valid_message = None

157

158

def get_form_valid_message(self):

159

"""Validate that form_valid_message is set correctly"""

160

161

def form_valid(self, form):

162

"""Set form valid message for standard validation"""

163

164

def delete(self, *args, **kwargs):

165

"""Set form valid message for delete operations"""

166

167

class FormInvalidMessageMixin(MessageMixin):

168

"""Set message when form fails validation"""

169

form_invalid_message = None

170

171

def get_form_invalid_message(self):

172

"""Validate that form_invalid_message is set correctly"""

173

174

def form_invalid(self, form):

175

"""Set form invalid message for validation failures"""

176

177

class FormMessagesMixin(FormValidMessageMixin, FormInvalidMessageMixin):

178

"""Combines valid and invalid message mixins"""

179

```

180

181

Usage examples:

182

183

```python

184

from django.views.generic import CreateView, UpdateView

185

from braces.views import FormValidMessageMixin, FormInvalidMessageMixin, FormMessagesMixin

186

187

# Success messages only

188

class CreateWithSuccessView(FormValidMessageMixin, CreateView):

189

model = MyModel

190

form_valid_message = "Item created successfully!"

191

192

# Error messages only

193

class UpdateWithErrorView(FormInvalidMessageMixin, UpdateView):

194

model = MyModel

195

form_invalid_message = "Please correct the errors below."

196

197

# Both success and error messages

198

class FullMessageView(FormMessagesMixin, CreateView):

199

model = MyModel

200

form_valid_message = "Item created successfully!"

201

form_invalid_message = "Please fix the form errors."

202

```

203

204

### Advanced Message Usage

205

206

Direct access to Django's messages framework:

207

208

```python

209

from django.views.generic import FormView

210

from braces.views import MessageMixin

211

212

class CustomMessageView(MessageMixin, FormView):

213

def form_valid(self, form):

214

# Direct message usage

215

self.messages.success("Form submitted successfully!")

216

self.messages.info("Processing will begin shortly.")

217

218

# Conditional messaging

219

if form.cleaned_data.get('notify_admin'):

220

self.messages.warning("Admin will be notified.")

221

222

return super().form_valid(form)

223

224

def form_invalid(self, form):

225

self.messages.error("There were errors in your submission.")

226

227

# Add specific field errors

228

for field, errors in form.errors.items():

229

for error in errors:

230

self.messages.error(f"{field}: {error}")

231

232

return super().form_invalid(form)

233

```

234

235

## Common Usage Patterns

236

237

### Complete Form Processing Pipeline

238

239

Combine multiple mixins for comprehensive form handling:

240

241

```python

242

from django.views.generic import CreateView

243

from braces.views import (

244

LoginRequiredMixin, UserFormKwargsMixin,

245

FormMessagesMixin, SuccessURLRedirectListMixin

246

)

247

248

class CompleteCreateView(

249

LoginRequiredMixin,

250

UserFormKwargsMixin,

251

FormMessagesMixin,

252

SuccessURLRedirectListMixin,

253

CreateView

254

):

255

model = MyModel

256

form_class = MyModelForm

257

login_url = '/login/'

258

form_valid_message = "Item created successfully!"

259

form_invalid_message = "Please correct the errors below."

260

success_list_url = 'myapp:item_list'

261

```

262

263

### API Form Processing

264

265

Combine with JSON mixins for API endpoints:

266

267

```python

268

from django.views.generic import CreateView

269

from braces.views import CsrfExemptMixin, JsonRequestResponseMixin, UserFormKwargsMixin

270

271

class APIFormView(CsrfExemptMixin, JsonRequestResponseMixin, UserFormKwargsMixin, CreateView):

272

model = MyModel

273

form_class = MyModelForm

274

275

def form_valid(self, form):

276

# Save object

277

self.object = form.save()

278

279

# Return JSON response

280

return self.render_json_response({

281

'success': True,

282

'id': self.object.pk,

283

'message': 'Created successfully'

284

}, status=201)

285

286

def form_invalid(self, form):

287

# Return form errors as JSON

288

return self.render_json_response({

289

'success': False,

290

'errors': form.errors

291

}, status=400)

292

```

293

294

### Conditional Form Processing

295

296

Dynamic form behavior based on user or context:

297

298

```python

299

from django.views.generic import UpdateView

300

from braces.views import UserFormKwargsMixin, FormMessagesMixin

301

302

class ConditionalUpdateView(UserFormKwargsMixin, FormMessagesMixin, UpdateView):

303

model = MyModel

304

305

def get_form_valid_message(self):

306

if self.request.user.is_staff:

307

return "Administrative update completed."

308

return "Your changes have been saved."

309

310

def get_form_invalid_message(self):

311

return "Please correct the errors and try again."

312

313

def form_valid(self, form):

314

# Custom validation based on user

315

if not self.request.user.is_staff:

316

# Remove admin-only changes

317

form.instance.admin_approved = False

318

319

return super().form_valid(form)

320

```