def test_transmute(self): doctype = DocumentType.objects.create(name='transmuted') doc = Document( document_type = doctype, ) doc.save() uf = UploadedFile.transmute_document( doc, uploader=self.test_user, ) uf.save() self.assertEqual(uf.document_ptr_id, doc.id) self.assertEqual(uf.document_ptr, doc) self.assertEqual(uf.document_type, doc.document_type) self.assertEqual(doc.uploadedfile, uf) self.assertRaises(ValueError, UploadedFile.transmute_document, doc, uploader=self.test_user)
def add_document(request, documentable_id): obj = Documentable.objects.get(id=documentable_id).specific_instance() # even though only one subclass of Document is listed here, this view is # written with adding new ones in mind form_classes = { 'document': NewDocumentForm, 'uploaded_file': NewUploadedFileForm, } form_kwargs = {} for name in form_classes.keys(): form_kwargs[name] = { 'prefix': name, } forms = {} if request.method == 'POST': # we have to instantiate the 'document' form in order to know which other # forms to bind form_kwargs['document']['data'] = request.POST forms['document'] = form_classes['document'](**form_kwargs['document']) # we only want to bind the forms the user acutally filled in if forms['document'].is_valid(): is_upload = forms['document'].cleaned_data['is_uploadedfile'] if is_upload: form_kwargs['uploaded_file']['data'] = request.POST form_kwargs['uploaded_file']['files'] = request.FILES # now instantiate the forms besides the 'document' form for name in filter(lambda fn: fn != 'document', form_classes.keys()): forms[name] = form_classes[name](**form_kwargs[name]) if forms['document'].is_valid() and (not is_upload or (is_upload and forms['uploaded_file'].is_valid())): document = forms['document'].save(commit=False) document.attached_to = obj document.save() forms['document'].save_m2m() if is_upload: uploaded_file = UploadedFile.transmute_document(document, **forms['uploaded_file'].cleaned_data) uploaded_file.uploader = request.user uploaded_file.clean() uploaded_file.save() return redirect(obj) else: # request.method != 'POST' for name in form_classes.keys(): forms[name] = form_classes[name](**form_kwargs[name]) # the default template uses the radiohider script with forms['models'] # select widget. TODO currently no way to pass in a custom Media to go with # a custom template. template_media = Media( js= (settings.JQUERY_FILE, 'checkboxhider.js'), ) media = reduce( lambda m, f: m + f.media, forms.values(), template_media) return render_to_response( 'documents/add_attachment.html', { 'object': obj, 'forms': forms, 'media': media, }, context_instance= RequestContext(request), )