Mercurial > public > sg101
comparison gpp/forums/forms.py @ 286:72fd300685d5
For #95. You can now make posts with no text in the body if you have attachments. And now if you create a new topic with an attachment, and the POST fails (say you forgot the topic title), we will now re-attach attachments. Also fixed a bug in the smiley code that would arise if it was asked to markup an empty string.
author | Brian Neal <bgneal@gmail.com> |
---|---|
date | Sat, 23 Oct 2010 20:19:46 +0000 |
parents | 8fd4984d5c3b |
children | 26fc9ac9a0eb |
comparison
equal
deleted
inserted
replaced
285:8fd4984d5c3b | 286:72fd300685d5 |
---|---|
10 from forums.attachments import AttachmentProcessor | 10 from forums.attachments import AttachmentProcessor |
11 | 11 |
12 | 12 |
13 class NewPostForm(forms.Form): | 13 class NewPostForm(forms.Form): |
14 """Form for creating a new post.""" | 14 """Form for creating a new post.""" |
15 body = forms.CharField(label='', | 15 body = forms.CharField(label='', |
16 required=False, | |
16 widget=forms.Textarea(attrs={'class': 'markItUp smileyTarget'})) | 17 widget=forms.Textarea(attrs={'class': 'markItUp smileyTarget'})) |
17 topic_id = forms.IntegerField(widget=forms.HiddenInput) | 18 topic_id = forms.IntegerField(widget=forms.HiddenInput) |
18 topic = None | 19 topic = None |
19 | 20 |
20 class Media: | 21 class Media: |
21 css = { | 22 css = { |
22 'all': (settings.GPP_THIRD_PARTY_CSS['markitup'] + | 23 'all': (settings.GPP_THIRD_PARTY_CSS['markitup'] + |
23 settings.GPP_THIRD_PARTY_CSS['jquery-ui']), | 24 settings.GPP_THIRD_PARTY_CSS['jquery-ui']), |
24 } | 25 } |
25 js = (settings.GPP_THIRD_PARTY_JS['markitup'] + | 26 js = (settings.GPP_THIRD_PARTY_JS['markitup'] + |
26 settings.GPP_THIRD_PARTY_JS['jquery-ui'] + | 27 settings.GPP_THIRD_PARTY_JS['jquery-ui'] + |
27 ('js/forums.js', )) | 28 ('js/forums.js', )) |
28 | 29 |
29 def __init__(self, *args, **kwargs): | 30 def __init__(self, *args, **kwargs): |
30 super(NewPostForm, self).__init__(*args, **kwargs) | 31 super(NewPostForm, self).__init__(*args, **kwargs) |
31 attachments = args[0].getlist('attachment') if len(args) else [] | 32 attachments = args[0].getlist('attachment') if len(args) else [] |
32 self.attach_proc = AttachmentProcessor(attachments) | 33 self.attach_proc = AttachmentProcessor(attachments) |
34 | |
35 def clean_body(self): | |
36 data = self.cleaned_data['body'] | |
37 if not data and not self.attach_proc.has_attachments(): | |
38 raise forms.ValidationError("This field is required.") | |
39 return data | |
33 | 40 |
34 def clean_topic_id(self): | 41 def clean_topic_id(self): |
35 id = self.cleaned_data['topic_id'] | 42 id = self.cleaned_data['topic_id'] |
36 try: | 43 try: |
37 self.topic = Topic.objects.select_related().get(pk=id) | 44 self.topic = Topic.objects.select_related().get(pk=id) |
38 except Topic.DoesNotExist: | 45 except Topic.DoesNotExist: |
39 raise forms.ValidationError('invalid topic') | 46 raise forms.ValidationError('invalid topic') |
40 return id | 47 return id |
41 | 48 |
42 def save(self, user, ip=None): | 49 def save(self, user, ip=None): |
43 """ | 50 """ |
44 Creates a new post from the form data and supplied arguments. | 51 Creates a new post from the form data and supplied arguments. |
45 """ | 52 """ |
56 Superusers and moderators can also create the topic as a sticky or initially | 63 Superusers and moderators can also create the topic as a sticky or initially |
57 locked. | 64 locked. |
58 """ | 65 """ |
59 name = forms.CharField(label='Subject', max_length=255, | 66 name = forms.CharField(label='Subject', max_length=255, |
60 widget=forms.TextInput(attrs={'size': 64})) | 67 widget=forms.TextInput(attrs={'size': 64})) |
61 body = forms.CharField(label='', | 68 body = forms.CharField(label='', required=False, |
62 widget=forms.Textarea(attrs={'class': 'markItUp smileyTarget'})) | 69 widget=forms.Textarea(attrs={'class': 'markItUp smileyTarget'})) |
63 user = None | 70 user = None |
64 forum = None | 71 forum = None |
65 has_mod_fields = False | 72 has_mod_fields = False |
66 | 73 |
67 class Media: | 74 class Media: |
68 css = { | 75 css = { |
69 'all': (settings.GPP_THIRD_PARTY_CSS['markitup'] + | 76 'all': (settings.GPP_THIRD_PARTY_CSS['markitup'] + |
70 settings.GPP_THIRD_PARTY_CSS['jquery-ui']), | 77 settings.GPP_THIRD_PARTY_CSS['jquery-ui']), |
71 } | 78 } |
72 js = (settings.GPP_THIRD_PARTY_JS['markitup'] + | 79 js = (settings.GPP_THIRD_PARTY_JS['markitup'] + |
73 settings.GPP_THIRD_PARTY_JS['jquery-ui'] + | 80 settings.GPP_THIRD_PARTY_JS['jquery-ui'] + |
74 ('js/forums.js', )) | 81 ('js/forums.js', )) |
75 | 82 |
76 def __init__(self, user, forum, *args, **kwargs): | 83 def __init__(self, user, forum, *args, **kwargs): |
77 super(NewTopicForm, self).__init__(*args, **kwargs) | 84 super(NewTopicForm, self).__init__(*args, **kwargs) |
83 self.fields['locked'] = forms.BooleanField(required=False) | 90 self.fields['locked'] = forms.BooleanField(required=False) |
84 self.has_mod_fields = True | 91 self.has_mod_fields = True |
85 | 92 |
86 attachments = args[0].getlist('attachment') if len(args) else [] | 93 attachments = args[0].getlist('attachment') if len(args) else [] |
87 self.attach_proc = AttachmentProcessor(attachments) | 94 self.attach_proc = AttachmentProcessor(attachments) |
95 | |
96 # If this form is being POSTed, and the user is trying to add | |
97 # attachments, create hidden fields to list the Oembed ids. In | |
98 # case the form isn't valid, the client-side javascript will know | |
99 # which Oembed media to ask for when the form is displayed with | |
100 # errors. | |
101 if self.attach_proc.has_attachments(): | |
102 pks = self.attach_proc.get_ids() | |
103 self.fields['attachment'] = forms.MultipleChoiceField(label='', | |
104 widget=forms.MultipleHiddenInput(), | |
105 choices=[(v, v) for v in pks]) | |
106 | |
107 def clean_body(self): | |
108 data = self.cleaned_data['body'] | |
109 if not data and not self.attach_proc.has_attachments(): | |
110 raise forms.ValidationError("This field is required.") | |
111 return data | |
88 | 112 |
89 def save(self, ip=None): | 113 def save(self, ip=None): |
90 """ | 114 """ |
91 Creates the new Topic and first Post from the form data and supplied | 115 Creates the new Topic and first Post from the form data and supplied |
92 arguments. | 116 arguments. |
111 | 135 |
112 class PostForm(forms.ModelForm): | 136 class PostForm(forms.ModelForm): |
113 """ | 137 """ |
114 Form for editing an existing post or a new, non-quick post. | 138 Form for editing an existing post or a new, non-quick post. |
115 """ | 139 """ |
116 body = forms.CharField(label='', | 140 body = forms.CharField(label='', |
141 required=False, | |
117 widget=forms.Textarea(attrs={'class': 'markItUp smileyTarget'})) | 142 widget=forms.Textarea(attrs={'class': 'markItUp smileyTarget'})) |
118 | 143 |
119 class Meta: | 144 class Meta: |
120 model = Post | 145 model = Post |
121 fields = ('body', ) | 146 fields = ('body', ) |
123 class Media: | 148 class Media: |
124 css = { | 149 css = { |
125 'all': (settings.GPP_THIRD_PARTY_CSS['markitup'] + | 150 'all': (settings.GPP_THIRD_PARTY_CSS['markitup'] + |
126 settings.GPP_THIRD_PARTY_CSS['jquery-ui']), | 151 settings.GPP_THIRD_PARTY_CSS['jquery-ui']), |
127 } | 152 } |
128 js = (settings.GPP_THIRD_PARTY_JS['markitup'] + | 153 js = (settings.GPP_THIRD_PARTY_JS['markitup'] + |
129 settings.GPP_THIRD_PARTY_JS['jquery-ui'] + | 154 settings.GPP_THIRD_PARTY_JS['jquery-ui'] + |
130 ('js/forums.js', )) | 155 ('js/forums.js', )) |
131 | 156 |
157 def __init__(self, *args, **kwargs): | |
158 super(PostForm, self).__init__(*args, **kwargs) | |
159 | |
160 attachments = args[0].getlist('attachment') if len(args) else [] | |
161 self.attach_proc = AttachmentProcessor(attachments) | |
162 | |
163 # If this form is being used to edit an existing post, and that post | |
164 # has attachments, create a hidden post_id field. The client-side | |
165 # AJAX will use this as a cue to retrieve the HTML for the embedded | |
166 # media. | |
167 if 'instance' in kwargs: | |
168 post = kwargs['instance'] | |
169 if post.attachments.count(): | |
170 self.fields['post_id'] = forms.CharField(label='', | |
171 widget=forms.HiddenInput(attrs={'value': post.id})) | |
172 | |
173 def clean_body(self): | |
174 data = self.cleaned_data['body'] | |
175 if not data and not self.attach_proc.has_attachments(): | |
176 raise forms.ValidationError('This field is required.') | |
177 return data | |
178 | |
132 | 179 |
133 class MoveTopicForm(forms.Form): | 180 class MoveTopicForm(forms.Form): |
134 """ | 181 """ |
135 Form for a moderator to move a topic to a forum. | 182 Form for a moderator to move a topic to a forum. |
136 """ | 183 """ |
137 forums = forms.ModelChoiceField(label='Move to forum', | 184 forums = forms.ModelChoiceField(label='Move to forum', |
138 queryset=Forum.objects.none()) | 185 queryset=Forum.objects.none()) |
139 | 186 |
140 def __init__(self, user, *args, **kwargs): | 187 def __init__(self, user, *args, **kwargs): |
141 hide_label = kwargs.pop('hide_label', False) | 188 hide_label = kwargs.pop('hide_label', False) |
142 required = kwargs.pop('required', True) | 189 required = kwargs.pop('required', True) |
143 super(MoveTopicForm, self).__init__(*args, **kwargs) | 190 super(MoveTopicForm, self).__init__(*args, **kwargs) |
144 self.fields['forums'].queryset = \ | 191 self.fields['forums'].queryset = \ |
145 Forum.objects.forums_for_user(user).order_by('name') | 192 Forum.objects.forums_for_user(user).order_by('name') |
146 if hide_label: | 193 if hide_label: |
152 """ | 199 """ |
153 Form for a moderator to split posts from a topic to a new topic. | 200 Form for a moderator to split posts from a topic to a new topic. |
154 """ | 201 """ |
155 name = forms.CharField(label='New topic title', max_length=255, | 202 name = forms.CharField(label='New topic title', max_length=255, |
156 widget=forms.TextInput(attrs={'size': 64})) | 203 widget=forms.TextInput(attrs={'size': 64})) |
157 forums = forms.ModelChoiceField(label='Forum for new topic', | 204 forums = forms.ModelChoiceField(label='Forum for new topic', |
158 queryset=Forum.objects.none()) | 205 queryset=Forum.objects.none()) |
159 post_ids = [] | 206 post_ids = [] |
160 split_at = False | 207 split_at = False |
161 | 208 |
162 def __init__(self, user, *args, **kwargs): | 209 def __init__(self, user, *args, **kwargs): |