Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed #4572 -- Added an example of form_for_instance usage in a full-…

…fledged view. Based on a patch from toddobryan@mac.com.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@5988 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit c06524bc2d132e80cb4602e5b8bffc6f3378b5d4 1 parent 46ec6b3
Malcolm Tredinnick authored August 20, 2007

Showing 2 changed files with 57 additions and 20 deletions. Show diff stats Hide diff stats

  1. 1  AUTHORS
  2. 76  docs/newforms.txt
1  AUTHORS
@@ -213,6 +213,7 @@ answer newbie questions, and generally made Django that much better:
213 213
     Fraser Nevett <mail@nevett.org>
214 214
     Sam Newman <http://www.magpiebrain.com/>
215 215
     Neal Norwitz <nnorwitz@google.com>
  216
+    Todd O'Bryan <toddobryan@mac.com>
216 217
     oggie rob <oz.robharvey@gmail.com>
217 218
     Jay Parlar <parlar@gmail.com>
218 219
     pavithran s <pavithran.s@gmail.com>
76  docs/newforms.txt
@@ -1459,10 +1459,10 @@ commonly used groups of widgets:
1459 1459
     ``Textarea``                  ``<textarea>...</textarea>``
1460 1460
     ``CheckboxInput``             ``<input type='checkbox' ...``
1461 1461
     ``Select``                    ``<select><option ...``
1462  
-    ``NullBooleanSelect``         Select widget with options 'Unknown', 
  1462
+    ``NullBooleanSelect``         Select widget with options 'Unknown',
1463 1463
                                   'Yes' and 'No'
1464 1464
     ``SelectMultiple``            ``<select multiple='multiple'><option ...``
1465  
-    ``RadioSelect``               ``<ul><li><input type='radio' ...`` 
  1465
+    ``RadioSelect``               ``<ul><li><input type='radio' ...``
1466 1466
     ``CheckboxSelectMultiple``    ``<ul><li><input type='checkbox' ...``
1467 1467
     ``MultiWidget``               Wrapper around multiple other widgets
1468 1468
     ``SplitDateTimeWidget``       Wrapper around two ``TextInput`` widgets:
@@ -1473,19 +1473,19 @@ Specifying widgets
1473 1473
 ------------------
1474 1474
 
1475 1475
 Whenever you specify a field on a form, Django will use a default widget
1476  
-that is appropriate to the type of data that is to be displayed. To find 
  1476
+that is appropriate to the type of data that is to be displayed. To find
1477 1477
 which widget is used on which field, see the documentation for the
1478 1478
 built-in Field classes.
1479 1479
 
1480  
-However, if you want to use a different widget for a field, you can - 
  1480
+However, if you want to use a different widget for a field, you can -
1481 1481
 just use the 'widget' argument on the field definition. For example::
1482 1482
 
1483 1483
     class CommentForm(forms.Form):
1484 1484
         name = forms.CharField()
1485 1485
         url = forms.URLField()
1486 1486
         comment = forms.CharField(widget=forms.Textarea)
1487  
-        
1488  
-This would specify a form with a comment that uses a larger Textarea widget, 
  1487
+
  1488
+This would specify a form with a comment that uses a larger Textarea widget,
1489 1489
 rather than the default TextInput widget.
1490 1490
 
1491 1491
 Customizing widget instances
@@ -1496,8 +1496,8 @@ HTML - Django doesn't add a class definition, or any other widget-specific
1496 1496
 attributes. This means that all 'TextInput' widgets will appear the same
1497 1497
 on your web page.
1498 1498
 
1499  
-If you want to make one widget look different to another, you need to 
1500  
-specify additional attributes for each widget. When you specify a 
  1499
+If you want to make one widget look different to another, you need to
  1500
+specify additional attributes for each widget. When you specify a
1501 1501
 widget, you can provide a list of attributes that will be added to the
1502 1502
 rendered HTML for the widget.
1503 1503
 
@@ -1519,13 +1519,13 @@ each widget will be rendered exactly the same::
1519 1519
     <tr><th>Comment:</th><td><input type="text" name="comment" /></td></tr>
1520 1520
 
1521 1521
 On a real web page, you probably don't want every widget to look the same. You
1522  
-might want a larger input element for the comment, and you might want the 
1523  
-'name' widget to have some special CSS class. To do this, you specify a 
1524  
-custom widget for your fields, and specify some attributes to use 
  1522
+might want a larger input element for the comment, and you might want the
  1523
+'name' widget to have some special CSS class. To do this, you specify a
  1524
+custom widget for your fields, and specify some attributes to use
1525 1525
 when rendering those widgets::
1526 1526
 
1527 1527
     class CommentForm(forms.Form):
1528  
-        name = forms.CharField(                   
  1528
+        name = forms.CharField(
1529 1529
                     widget=forms.TextInput(attrs={'class':'special'}))
1530 1530
         url = forms.URLField()
1531 1531
         comment = forms.CharField(
@@ -1543,19 +1543,19 @@ Custom Widgets
1543 1543
 --------------
1544 1544
 
1545 1545
 When you start to write a lot of forms, you will probably find that you will
1546  
-reuse certain sets of widget attributes over and over again. Rather than 
1547  
-repeat these attribute definitions every time you need them, Django allows 
  1546
+reuse certain sets of widget attributes over and over again. Rather than
  1547
+repeat these attribute definitions every time you need them, Django allows
1548 1548
 you to capture those definitions as a custom widget.
1549 1549
 
1550 1550
 For example, if you find that you are including a lot of comment fields on forms,
1551  
-you could capture the idea of a ``TextInput`` with a specific ``size`` attribute 
  1551
+you could capture the idea of a ``TextInput`` with a specific ``size`` attribute
1552 1552
 as a custom extension to the ``TextInput`` widget::
1553 1553
 
1554 1554
     class CommentWidget(forms.TextInput):
1555 1555
         def __init__(self, *args, **kwargs):
1556 1556
             kwargs.setdefault('attrs',{}).update({'size': '40'})
1557 1557
             super(forms.TextInput, self).__init__(*args, **kwargs)
1558  
-            
  1558
+
1559 1559
 Then you can use this widget in your forms::
1560 1560
 
1561 1561
     class CommentForm(forms.Form):
@@ -1563,8 +1563,8 @@ Then you can use this widget in your forms::
1563 1563
         url = forms.URLField()
1564 1564
         comment = forms.CharField(widget=CommentWidget)
1565 1565
 
1566  
-You can even customize your custom widget, in the same way as you would 
1567  
-any other widget. Adding a once-off class to your ``CommentWidget`` is as 
  1566
+You can even customize your custom widget, in the same way as you would
  1567
+any other widget. Adding a once-off class to your ``CommentWidget`` is as
1568 1568
 simple as adding an attribute definition::
1569 1569
 
1570 1570
     class CommentForm(forms.Form):
@@ -1579,14 +1579,14 @@ by defining::
1579 1579
 
1580 1580
     class CommentInput(forms.CharField):
1581 1581
         widget = CommentWidget
1582  
-        
  1582
+
1583 1583
 You can then use this field whenever you have a form that requires a comment::
1584 1584
 
1585 1585
     class CommentForm(forms.Form):
1586 1586
         name = forms.CharField()
1587 1587
         url = forms.URLField()
1588 1588
         comment = CommentInput()
1589  
-        
  1589
+
1590 1590
 Generating forms for models
1591 1591
 ===========================
1592 1592
 
@@ -1931,6 +1931,42 @@ will raise ``ValueError`` if the data doesn't validate.
1931 1931
 ``form_for_instance()`` has ``form``, ``fields`` and ``formfield_callback``
1932 1932
 arguments that behave the same way as they do for ``form_for_model()``.
1933 1933
 
  1934
+Let's modify the earlier `contact form`_ view example a little bit. Suppose we
  1935
+have a ``Message`` model that holds each contact submission. Something like::
  1936
+
  1937
+    class Message(models.Model):
  1938
+        subject = models.CharField(max_length=100)
  1939
+        message = models.TextField()
  1940
+        sender = models.EmailField()
  1941
+        cc_myself = models.BooleanField()
  1942
+
  1943
+You could use this model to create a form (using ``form_for_model()``). You
  1944
+could also use existing ``Message`` instances to create a form for editing
  1945
+messages. The earlier_ view can be changed slightly to accept the ``id`` value
  1946
+of an existing ``Message`` and present it for editing::
  1947
+
  1948
+    def contact_edit(request, msg_id):
  1949
+        # Create the form from the message id.
  1950
+        message = get_object_or_404(Message, id=msg_id)
  1951
+        ContactForm = form_for_instance(message)
  1952
+
  1953
+        if request.method == 'POST':
  1954
+            form = ContactForm(request.POST)
  1955
+            if form.is_valid():
  1956
+                form.save()
  1957
+                return HttpResponseRedirect('/url/on_success/')
  1958
+        else:
  1959
+            form = ContactForm()
  1960
+        return render_to_response('contact.html', {'form': form})
  1961
+
  1962
+Aside from how we create the ``ContactForm`` class here, the main point to
  1963
+note is that the form display in the ``GET`` branch of the function
  1964
+will use the values from the ``message`` instance as initial values for the
  1965
+form field.
  1966
+
  1967
+.. _contact form: `Simple view example`_
  1968
+.. _earlier: `Simple view example`_
  1969
+
1934 1970
 When should you use ``form_for_model()`` and ``form_for_instance()``?
1935 1971
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1936 1972
 

0 notes on commit c06524b

Please sign in to comment.
Something went wrong with that request. Please try again.