Mercurial > public > sg101
comparison forums/forms.py @ 581:ee87ea74d46b
For Django 1.4, rearranged project structure for new manage.py.
author | Brian Neal <bgneal@gmail.com> |
---|---|
date | Sat, 05 May 2012 17:10:48 -0500 |
parents | gpp/forums/forms.py@bbbc357ac5f3 |
children | 92101013d5ac |
comparison
equal
deleted
inserted
replaced
580:c525f3e0b5d0 | 581:ee87ea74d46b |
---|---|
1 """ | |
2 Forms for the forums application. | |
3 | |
4 """ | |
5 from django import forms | |
6 from django.conf import settings | |
7 | |
8 from forums.models import Forum | |
9 from forums.models import Topic | |
10 from forums.models import Post | |
11 from forums.attachments import AttachmentProcessor | |
12 import forums.permissions as perms | |
13 from forums.signals import notify_new_topic, notify_new_post | |
14 | |
15 | |
16 class NewPostForm(forms.Form): | |
17 """Form for creating a new post.""" | |
18 body = forms.CharField(label='', | |
19 required=False, | |
20 widget=forms.Textarea(attrs={'class': 'markItUp smileyTarget'})) | |
21 topic_id = forms.IntegerField(widget=forms.HiddenInput) | |
22 topic = None | |
23 | |
24 class Media: | |
25 css = { | |
26 'all': (settings.GPP_THIRD_PARTY_CSS['markitup'] + | |
27 settings.GPP_THIRD_PARTY_CSS['jquery-ui']), | |
28 } | |
29 js = (settings.GPP_THIRD_PARTY_JS['markitup'] + | |
30 settings.GPP_THIRD_PARTY_JS['jquery-ui'] + | |
31 ['js/forums.js']) | |
32 | |
33 def __init__(self, *args, **kwargs): | |
34 super(NewPostForm, self).__init__(*args, **kwargs) | |
35 attachments = args[0].getlist('attachment') if len(args) else [] | |
36 self.attach_proc = AttachmentProcessor(attachments) | |
37 | |
38 def clean_body(self): | |
39 data = self.cleaned_data['body'] | |
40 if not data and not self.attach_proc.has_attachments(): | |
41 raise forms.ValidationError("This field is required.") | |
42 return data | |
43 | |
44 def clean_topic_id(self): | |
45 id = self.cleaned_data['topic_id'] | |
46 try: | |
47 self.topic = Topic.objects.select_related().get(pk=id) | |
48 except Topic.DoesNotExist: | |
49 raise forms.ValidationError('invalid topic') | |
50 return id | |
51 | |
52 def save(self, user, ip=None): | |
53 """ | |
54 Creates a new post from the form data and supplied arguments. | |
55 """ | |
56 post = Post(topic=self.topic, user=user, body=self.cleaned_data['body'], | |
57 user_ip=ip) | |
58 post.save() | |
59 self.attach_proc.save_attachments(post) | |
60 notify_new_post(post) | |
61 return post | |
62 | |
63 | |
64 class NewTopicForm(forms.Form): | |
65 """ | |
66 Form for creating a new topic and 1st post to that topic. | |
67 Superusers and moderators can also create the topic as a sticky or initially | |
68 locked. | |
69 """ | |
70 name = forms.CharField(label='Subject', max_length=255, | |
71 widget=forms.TextInput(attrs={'size': 64})) | |
72 body = forms.CharField(label='', required=False, | |
73 widget=forms.Textarea(attrs={'class': 'markItUp smileyTarget'})) | |
74 user = None | |
75 forum = None | |
76 has_mod_fields = False | |
77 | |
78 class Media: | |
79 css = { | |
80 'all': (settings.GPP_THIRD_PARTY_CSS['markitup'] + | |
81 settings.GPP_THIRD_PARTY_CSS['jquery-ui']), | |
82 } | |
83 js = (settings.GPP_THIRD_PARTY_JS['markitup'] + | |
84 settings.GPP_THIRD_PARTY_JS['jquery-ui'] + | |
85 ['js/forums.js']) | |
86 | |
87 def __init__(self, user, forum, *args, **kwargs): | |
88 super(NewTopicForm, self).__init__(*args, **kwargs) | |
89 self.user = user | |
90 self.forum = forum | |
91 | |
92 if perms.can_moderate(forum, user): | |
93 self.fields['sticky'] = forms.BooleanField(required=False) | |
94 self.fields['locked'] = forms.BooleanField(required=False) | |
95 self.has_mod_fields = True | |
96 | |
97 attachments = args[0].getlist('attachment') if len(args) else [] | |
98 self.attach_proc = AttachmentProcessor(attachments) | |
99 | |
100 # If this form is being POSTed, and the user is trying to add | |
101 # attachments, create hidden fields to list the Oembed ids. In | |
102 # case the form isn't valid, the client-side javascript will know | |
103 # which Oembed media to ask for when the form is displayed with | |
104 # errors. | |
105 if self.attach_proc.has_attachments(): | |
106 pks = self.attach_proc.get_ids() | |
107 self.fields['attachment'] = forms.MultipleChoiceField(label='', | |
108 widget=forms.MultipleHiddenInput(), | |
109 choices=[(v, v) for v in pks]) | |
110 | |
111 def clean_body(self): | |
112 data = self.cleaned_data['body'] | |
113 if not data and not self.attach_proc.has_attachments(): | |
114 raise forms.ValidationError("This field is required.") | |
115 return data | |
116 | |
117 def save(self, ip=None): | |
118 """ | |
119 Creates the new Topic and first Post from the form data and supplied | |
120 arguments. | |
121 """ | |
122 topic = Topic(forum=self.forum, | |
123 name=self.cleaned_data['name'], | |
124 user=self.user, | |
125 sticky=self.has_mod_fields and self.cleaned_data['sticky'], | |
126 locked=self.has_mod_fields and self.cleaned_data['locked']) | |
127 topic.save() | |
128 | |
129 post = Post(topic=topic, | |
130 user=self.user, | |
131 body=self.cleaned_data['body'], | |
132 user_ip=ip) | |
133 post.save() | |
134 | |
135 self.attach_proc.save_attachments(post) | |
136 | |
137 notify_new_topic(topic) | |
138 notify_new_post(post) | |
139 | |
140 return topic | |
141 | |
142 | |
143 class PostForm(forms.ModelForm): | |
144 """ | |
145 Form for editing an existing post or a new, non-quick post. | |
146 """ | |
147 body = forms.CharField(label='', | |
148 required=False, | |
149 widget=forms.Textarea(attrs={'class': 'markItUp smileyTarget'})) | |
150 | |
151 class Meta: | |
152 model = Post | |
153 fields = ('body', ) | |
154 | |
155 class Media: | |
156 css = { | |
157 'all': (settings.GPP_THIRD_PARTY_CSS['markitup'] + | |
158 settings.GPP_THIRD_PARTY_CSS['jquery-ui']), | |
159 } | |
160 js = (settings.GPP_THIRD_PARTY_JS['markitup'] + | |
161 settings.GPP_THIRD_PARTY_JS['jquery-ui'] + | |
162 ['js/forums.js']) | |
163 | |
164 def __init__(self, *args, **kwargs): | |
165 topic_name = kwargs.pop('topic_name', None) | |
166 super(PostForm, self).__init__(*args, **kwargs) | |
167 | |
168 if topic_name is not None: # this is a "first post" | |
169 self.fields.insert(0, 'name', forms.CharField(label='Subject', | |
170 max_length=255, | |
171 widget=forms.TextInput(attrs={'size': 64}))) | |
172 self.initial['name'] = topic_name | |
173 | |
174 attachments = args[0].getlist('attachment') if len(args) else [] | |
175 self.attach_proc = AttachmentProcessor(attachments) | |
176 | |
177 # If this form is being used to edit an existing post, and that post | |
178 # has attachments, create a hidden post_id field. The client-side | |
179 # AJAX will use this as a cue to retrieve the HTML for the embedded | |
180 # media. | |
181 if 'instance' in kwargs: | |
182 post = kwargs['instance'] | |
183 if post.attachments.count(): | |
184 self.fields['post_id'] = forms.CharField(label='', | |
185 widget=forms.HiddenInput(attrs={'value': post.id})) | |
186 | |
187 def clean_body(self): | |
188 data = self.cleaned_data['body'] | |
189 if not data and not self.attach_proc.has_attachments(): | |
190 raise forms.ValidationError('This field is required.') | |
191 return data | |
192 | |
193 def save(self, *args, **kwargs): | |
194 commit = kwargs.get('commit', False) | |
195 post = super(PostForm, self).save(*args, **kwargs) | |
196 | |
197 # Are we saving a "first post"? | |
198 if 'name' in self.cleaned_data: | |
199 post.topic.name = self.cleaned_data['name'] | |
200 if commit: | |
201 post.topic.save() | |
202 return post | |
203 | |
204 | |
205 class MoveTopicForm(forms.Form): | |
206 """ | |
207 Form for a moderator to move a topic to a forum. | |
208 """ | |
209 forums = forms.ModelChoiceField(label='Move to forum', | |
210 queryset=Forum.objects.none()) | |
211 | |
212 def __init__(self, user, *args, **kwargs): | |
213 hide_label = kwargs.pop('hide_label', False) | |
214 required = kwargs.pop('required', True) | |
215 super(MoveTopicForm, self).__init__(*args, **kwargs) | |
216 self.fields['forums'].queryset = \ | |
217 Forum.objects.forums_for_user(user).order_by('name') | |
218 if hide_label: | |
219 self.fields['forums'].label = '' | |
220 self.fields['forums'].required = required | |
221 | |
222 | |
223 class SplitTopicForm(forms.Form): | |
224 """ | |
225 Form for a moderator to split posts from a topic to a new topic. | |
226 """ | |
227 name = forms.CharField(label='New topic title', max_length=255, | |
228 widget=forms.TextInput(attrs={'size': 64})) | |
229 forums = forms.ModelChoiceField(label='Forum for new topic', | |
230 queryset=Forum.objects.none()) | |
231 post_ids = [] | |
232 split_at = False | |
233 | |
234 def __init__(self, user, *args, **kwargs): | |
235 super(SplitTopicForm, self).__init__(*args, **kwargs) | |
236 self.fields['forums'].queryset = \ | |
237 Forum.objects.forums_for_user(user).order_by('name') | |
238 | |
239 def clean(self): | |
240 self.post_ids = self.data.getlist('post_ids') | |
241 if len(self.post_ids) == 0: | |
242 raise forms.ValidationError('Please select some posts') | |
243 | |
244 self.split_at = 'split-at' in self.data | |
245 if self.split_at and len(self.post_ids) > 1: | |
246 raise forms.ValidationError('Please select only one post to split the topic at') | |
247 | |
248 return self.cleaned_data |