| | 2897 | |
|---|
| | 2898 | # FormSets #################################################################### |
|---|
| | 2899 | |
|---|
| | 2900 | FormSets allow you to create a bunch of instances of the same form class and |
|---|
| | 2901 | get back clean data as a list of dicts. |
|---|
| | 2902 | |
|---|
| | 2903 | >>> from django.newforms import formsets |
|---|
| | 2904 | |
|---|
| | 2905 | >>> class ChoiceForm(Form): |
|---|
| | 2906 | ... choice = CharField() |
|---|
| | 2907 | ... votes = IntegerField() |
|---|
| | 2908 | |
|---|
| | 2909 | |
|---|
| | 2910 | Create an empty form set |
|---|
| | 2911 | |
|---|
| | 2912 | >>> form_set = formsets.FormSet(ChoiceForm, prefix='choices', auto_id=False) |
|---|
| | 2913 | >>> for form in form_set.get_forms(): |
|---|
| | 2914 | ... print form.as_ul() |
|---|
| | 2915 | <li>Choice: <input type="text" name="choices-0-choice" /></li> |
|---|
| | 2916 | <li>Votes: <input type="text" name="choices-0-votes" /></li> |
|---|
| | 2917 | |
|---|
| | 2918 | |
|---|
| | 2919 | Forms pre-filled with initial data. |
|---|
| | 2920 | |
|---|
| | 2921 | >>> initial_data = [ |
|---|
| | 2922 | ... {'votes': 50, 'choice': u'The Doors', 'id': u'0'}, |
|---|
| | 2923 | ... {'votes': 51, 'choice': u'The Beatles', 'id': u'1'}, |
|---|
| | 2924 | ... ] |
|---|
| | 2925 | |
|---|
| | 2926 | >>> form_set = formsets.FormSet(ChoiceForm, initial=initial_data, auto_id=False, prefix='choices') |
|---|
| | 2927 | >>> print form_set.management_form.as_ul() |
|---|
| | 2928 | <input type="hidden" name="choices-COUNT" value="3" /> |
|---|
| | 2929 | |
|---|
| | 2930 | >>> for form in form_set.get_forms(): # print pre-filled forms |
|---|
| | 2931 | ... print form.as_ul() |
|---|
| | 2932 | <li>Choice: <input type="text" name="choices-0-choice" value="The Doors" /></li> |
|---|
| | 2933 | <li>Votes: <input type="text" name="choices-0-votes" value="50" /></li> |
|---|
| | 2934 | <li>Choice: <input type="text" name="choices-1-choice" value="The Beatles" /></li> |
|---|
| | 2935 | <li>Votes: <input type="text" name="choices-1-votes" value="51" /></li> |
|---|
| | 2936 | <li>Choice: <input type="text" name="choices-2-choice" /></li> |
|---|
| | 2937 | <li>Votes: <input type="text" name="choices-2-votes" /></li> |
|---|
| | 2938 | |
|---|
| | 2939 | |
|---|
| | 2940 | Tests for dealing with POSTed data |
|---|
| | 2941 | |
|---|
| | 2942 | >>> data = { |
|---|
| | 2943 | ... 'choices-COUNT': u'3', # the number of forms rendered |
|---|
| | 2944 | ... 'choices-0-choice': u'The Doors', |
|---|
| | 2945 | ... 'choices-0-votes': u'50', |
|---|
| | 2946 | ... 'choices-1-choice': u'The Beatles', |
|---|
| | 2947 | ... 'choices-1-votes': u'51', |
|---|
| | 2948 | ... 'choices-2-choice': u'', |
|---|
| | 2949 | ... 'choices-2-votes': u'', |
|---|
| | 2950 | ... } |
|---|
| | 2951 | |
|---|
| | 2952 | |
|---|
| | 2953 | >>> form_set = formsets.FormSet(ChoiceForm, data, auto_id=False, prefix='choices') |
|---|
| | 2954 | >>> print form_set.is_valid() |
|---|
| | 2955 | True |
|---|
| | 2956 | >>> for data in form_set.clean_data: |
|---|
| | 2957 | ... print data |
|---|
| | 2958 | {'votes': 50, 'choice': u'The Doors'} |
|---|
| | 2959 | {'votes': 51, 'choice': u'The Beatles'} |
|---|
| | 2960 | |
|---|
| | 2961 | |
|---|
| | 2962 | FormSet with deletion fields |
|---|
| | 2963 | |
|---|
| | 2964 | >>> form_set = formsets.FormSetWithDeletion(ChoiceForm, initial=initial_data, auto_id=False, prefix='choices') |
|---|
| | 2965 | >>> for form in form_set.get_forms(): # print pre-filled forms |
|---|
| | 2966 | ... print form.as_ul() |
|---|
| | 2967 | <li>Choice: <input type="text" name="choices-0-choice" value="The Doors" /></li> |
|---|
| | 2968 | <li>Votes: <input type="text" name="choices-0-votes" value="50" /></li> |
|---|
| | 2969 | <li>Delete: <input type="checkbox" name="choices-0-DELETE" /></li> |
|---|
| | 2970 | <li>Choice: <input type="text" name="choices-1-choice" value="The Beatles" /></li> |
|---|
| | 2971 | <li>Votes: <input type="text" name="choices-1-votes" value="51" /></li> |
|---|
| | 2972 | <li>Delete: <input type="checkbox" name="choices-1-DELETE" /></li> |
|---|
| | 2973 | <li>Choice: <input type="text" name="choices-2-choice" /></li> |
|---|
| | 2974 | <li>Votes: <input type="text" name="choices-2-votes" /></li> |
|---|
| | 2975 | <li>Delete: <input type="checkbox" name="choices-2-DELETE" /></li> |
|---|
| | 2976 | |
|---|
| | 2977 | >>> data = { |
|---|
| | 2978 | ... 'choices-COUNT': u'3', # the number of forms rendered |
|---|
| | 2979 | ... 'choices-0-choice': u'Fergie', |
|---|
| | 2980 | ... 'choices-0-votes': u'1000', |
|---|
| | 2981 | ... 'choices-0-DELETE': u'on', # Delete this choice. |
|---|
| | 2982 | ... 'choices-1-choice': u'The Decemberists', |
|---|
| | 2983 | ... 'choices-1-votes': u'150', |
|---|
| | 2984 | ... 'choices-2-choice': u'Calexico', |
|---|
| | 2985 | ... 'choices-2-votes': u'90', |
|---|
| | 2986 | ... } |
|---|
| | 2987 | |
|---|
| | 2988 | >>> form_set = formsets.FormSetWithDeletion(ChoiceForm, data, auto_id=False, prefix='choices') |
|---|
| | 2989 | >>> print form_set.is_valid() |
|---|
| | 2990 | True |
|---|
| | 2991 | |
|---|
| | 2992 | When we access form_set.clean_data, items marked for deletion won't be there, |
|---|
| | 2993 | but they *will* be in form_set.deleted_data |
|---|
| | 2994 | |
|---|
| | 2995 | >>> for data in form_set.clean_data: |
|---|
| | 2996 | ... print data |
|---|
| | 2997 | {'votes': 150, 'DELETE': False, 'choice': u'The Decemberists'} |
|---|
| | 2998 | {'votes': 90, 'DELETE': False, 'choice': u'Calexico'} |
|---|
| | 2999 | |
|---|
| | 3000 | >>> for data in form_set.deleted_data: |
|---|
| | 3001 | ... print data |
|---|
| | 3002 | {'votes': 1000, 'DELETE': True, 'choice': u'Fergie'} |
|---|
| | 3003 | |
|---|
| | 3004 | |
|---|
| | 3005 | FormSet with Ordering |
|---|
| | 3006 | |
|---|
| | 3007 | >>> form_set = formsets.FormSetWithOrdering(ChoiceForm, initial=initial_data, auto_id=False, prefix='choices') |
|---|
| | 3008 | >>> for form in form_set.get_forms(): # print pre-filled forms |
|---|
| | 3009 | ... print form.as_ul() |
|---|
| | 3010 | <li>Choice: <input type="text" name="choices-0-choice" value="The Doors" /></li> |
|---|
| | 3011 | <li>Votes: <input type="text" name="choices-0-votes" value="50" /></li> |
|---|
| | 3012 | <li>Order: <input type="text" name="choices-0-ORDER" value="1" /></li> |
|---|
| | 3013 | <li>Choice: <input type="text" name="choices-1-choice" value="The Beatles" /></li> |
|---|
| | 3014 | <li>Votes: <input type="text" name="choices-1-votes" value="51" /></li> |
|---|
| | 3015 | <li>Order: <input type="text" name="choices-1-ORDER" value="2" /></li> |
|---|
| | 3016 | <li>Choice: <input type="text" name="choices-2-choice" /></li> |
|---|
| | 3017 | <li>Votes: <input type="text" name="choices-2-votes" /></li> |
|---|
| | 3018 | <li>Order: <input type="text" name="choices-2-ORDER" value="3" /></li> |
|---|
| | 3019 | |
|---|
| | 3020 | >>> data = { |
|---|
| | 3021 | ... 'choices-COUNT': u'4', # the number of forms rendered |
|---|
| | 3022 | ... 'choices-0-choice': u'Fergie', |
|---|
| | 3023 | ... 'choices-0-votes': u'1000', |
|---|
| | 3024 | ... 'choices-0-ORDER': u'3', |
|---|
| | 3025 | ... 'choices-1-choice': u'The Decemberists', |
|---|
| | 3026 | ... 'choices-1-votes': u'150', |
|---|
| | 3027 | ... 'choices-1-ORDER': u'1', |
|---|
| | 3028 | ... 'choices-2-choice': u'Calexico', |
|---|
| | 3029 | ... 'choices-2-votes': u'90', |
|---|
| | 3030 | ... 'choices-2-ORDER': u'2', |
|---|
| | 3031 | ... 'choices-3-choice': u'', |
|---|
| | 3032 | ... 'choices-3-votes': u'', |
|---|
| | 3033 | ... 'choices-3-ORDER': u'4', |
|---|
| | 3034 | ... } |
|---|
| | 3035 | |
|---|
| | 3036 | >>> form_set = formsets.FormSetWithOrdering(ChoiceForm, data, auto_id=False, prefix='choices') |
|---|
| | 3037 | >>> print form_set.is_valid() |
|---|
| | 3038 | True |
|---|
| | 3039 | |
|---|
| | 3040 | The form_set.clean_data will be in the correct order as specified by the |
|---|
| | 3041 | ORDER field from each form. |
|---|
| | 3042 | |
|---|
| | 3043 | >>> for data in form_set.clean_data: |
|---|
| | 3044 | ... print data |
|---|
| | 3045 | {'votes': 150, 'ORDER': 1, 'choice': u'The Decemberists'} |
|---|
| | 3046 | {'votes': 90, 'ORDER': 2, 'choice': u'Calexico'} |
|---|
| | 3047 | {'votes': 1000, 'ORDER': 3, 'choice': u'Fergie'} |
|---|
| | 3048 | |
|---|