Django

Code

Changeset 5988

Show
Ignore:
Timestamp:
08/20/07 09:15:40 (1 year ago)
Author:
mtredinnick
Message:

Fixed #4572 -- Added an example of form_for_instance usage in a full-fledged view. Based on a patch from toddobryan@mac.com.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/trunk/AUTHORS

    r5987 r5988  
    214214    Sam Newman <http://www.magpiebrain.com/> 
    215215    Neal Norwitz <nnorwitz@google.com> 
     216    Todd O'Bryan <toddobryan@mac.com> 
    216217    oggie rob <oz.robharvey@gmail.com> 
    217218    Jay Parlar <parlar@gmail.com> 
  • django/trunk/docs/newforms.txt

    r5930 r5988  
    14601460    ``CheckboxInput``             ``<input type='checkbox' ...`` 
    14611461    ``Select``                    ``<select><option ...`` 
    1462     ``NullBooleanSelect``         Select widget with options 'Unknown',  
     1462    ``NullBooleanSelect``         Select widget with options 'Unknown', 
    14631463                                  'Yes' and 'No' 
    14641464    ``SelectMultiple``            ``<select multiple='multiple'><option ...`` 
    1465     ``RadioSelect``               ``<ul><li><input type='radio' ...``  
     1465    ``RadioSelect``               ``<ul><li><input type='radio' ...`` 
    14661466    ``CheckboxSelectMultiple``    ``<ul><li><input type='checkbox' ...`` 
    14671467    ``MultiWidget``               Wrapper around multiple other widgets 
     
    14741474 
    14751475Whenever 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  
     1476that is appropriate to the type of data that is to be displayed. To find 
    14771477which widget is used on which field, see the documentation for the 
    14781478built-in Field classes. 
    14791479 
    1480 However, if you want to use a different widget for a field, you can -  
     1480However, if you want to use a different widget for a field, you can - 
    14811481just use the 'widget' argument on the field definition. For example:: 
    14821482 
     
    14851485        url = forms.URLField() 
    14861486        comment = forms.CharField(widget=forms.Textarea) 
    1487          
    1488 This would specify a form with a comment that uses a larger Textarea widget,  
     1487 
     1488This would specify a form with a comment that uses a larger Textarea widget, 
    14891489rather than the default TextInput widget. 
    14901490 
     
    14971497on your web page. 
    14981498 
    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  
     1499If you want to make one widget look different to another, you need to 
     1500specify additional attributes for each widget. When you specify a 
    15011501widget, you can provide a list of attributes that will be added to the 
    15021502rendered HTML for the widget. 
     
    15201520 
    15211521On 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  
     1522might 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 
     1524custom widget for your fields, and specify some attributes to use 
    15251525when rendering those widgets:: 
    15261526 
    15271527    class CommentForm(forms.Form): 
    1528         name = forms.CharField(                    
     1528        name = forms.CharField( 
    15291529                    widget=forms.TextInput(attrs={'class':'special'})) 
    15301530        url = forms.URLField() 
     
    15441544 
    15451545When 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  
     1546reuse certain sets of widget attributes over and over again. Rather than 
     1547repeat these attribute definitions every time you need them, Django allows 
    15481548you to capture those definitions as a custom widget. 
    15491549 
    15501550For 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  
     1551you could capture the idea of a ``TextInput`` with a specific ``size`` attribute 
    15521552as a custom extension to the ``TextInput`` widget:: 
    15531553 
     
    15561556            kwargs.setdefault('attrs',{}).update({'size': '40'}) 
    15571557            super(forms.TextInput, self).__init__(*args, **kwargs) 
    1558              
     1558 
    15591559Then you can use this widget in your forms:: 
    15601560 
     
    15641564        comment = forms.CharField(widget=CommentWidget) 
    15651565 
    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  
     1566You can even customize your custom widget, in the same way as you would 
     1567any other widget. Adding a once-off class to your ``CommentWidget`` is as 
    15681568simple as adding an attribute definition:: 
    15691569 
     
    15801580    class CommentInput(forms.CharField): 
    15811581        widget = CommentWidget 
    1582          
     1582 
    15831583You can then use this field whenever you have a form that requires a comment:: 
    15841584 
     
    15871587        url = forms.URLField() 
    15881588        comment = CommentInput() 
    1589          
     1589 
    15901590Generating forms for models 
    15911591=========================== 
     
    19321932arguments that behave the same way as they do for ``form_for_model()``. 
    19331933 
     1934Let's modify the earlier `contact form`_ view example a little bit. Suppose we 
     1935have 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 
     1943You could use this model to create a form (using ``form_for_model()``). You 
     1944could also use existing ``Message`` instances to create a form for editing 
     1945messages. The earlier_ view can be changed slightly to accept the ``id`` value 
     1946of 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 
     1962Aside from how we create the ``ContactForm`` class here, the main point to 
     1963note is that the form display in the ``GET`` branch of the function 
     1964will use the values from the ``message`` instance as initial values for the 
     1965form field. 
     1966 
     1967.. _contact form: `Simple view example`_ 
     1968.. _earlier: `Simple view example`_ 
     1969 
    19341970When should you use ``form_for_model()`` and ``form_for_instance()``? 
    19351971~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~