0

I need your help, because I'm stuck in a project with no idea about how to continue.

I need to implement a simple "generic" document management app to integrate it in my project. I can have many kind of documents that are defined by "utilisation_type" in "DocumentType" model.

At the end, I need to display a page with an inline form, with only one of each "DocumentType" with (in this case) "utilisation_type"= "USER".

Like this, the user will get, for exemple, a page with 3 buttons, each button corresponding to only one DocumentType with "utilisation_type"= "USER" and he will be able to upload only one of each requested document.

Here are my models :

from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType

UTILISATION_TYPE_CHOICES = (
    ("USER", _(u"User")),
    ("PROJECT", _(u"Project")),
    ("TEAM", _(u"Team")),
    ("ALL", _(u"All")),
)

class DocumentType(models.Model):
    document_type = models.CharField(max_length=40, choices=DOCUMENT_TYPE_CHOICES)
    title = models.CharField(_(u'Titre'), max_length=255, blank=False, null=True)
    utilisation_type = models.CharField(max_length=15, choices=UTILISATION_TYPE_CHOICES)    

class Document(models.Model):
    document_type = models.ForeignKey(DocumentType)
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey('content_type', 'object_id')
    document = models.FileField(_(u"Document"), upload_to='upload/documents', null=True, blank=True)

class MyUserManager(BaseUserManager):
    first_name = models.CharField(_(u'Firstname'), max_length=90, blank=False)
    last_name = models.CharField(_(u'Lastname'), max_length=90, blank=False)

Here is my view :

@login_required
def documents(request):
    """
    User's documents edition
    """
    user = request.user
    DocumentInlineFormSet = generic_inlineformset_factory(Document)
    if request.method == 'POST':
        formset = DocumentInlineFormSet(request.POST, request.FILES, instance=user)
        if formset.is_valid():
            formset.save()
            messages.success(request, _(u'Profil updated'), fail_silently=True)
            return redirect('users.views.documents')
    else:
        formset = DocumentInlineFormSet(instance=user)
    return render_to_response('users/user_documents.html', {'formEditDocumentFormset': formset,}, context_instance=RequestContext(request))

I hope I've been clear enough in my explanation. Do not hesitate to ask more details if needed.

Bacteria
  • 8,406
  • 10
  • 50
  • 67
yann
  • 87
  • 2
  • 10
  • Unlike forum sites, we don't use "Thanks", or "Any help appreciated", or signatures on Stack Overflow. For more details see [Should 'Hi', 'thanks,' taglines, and salutations be removed from posts?](http://meta.stackexchange.com/questions/2950/should-hi-thanks-taglines-and-salutations-be-removed-from-posts) – Bacteria Aug 29 '15 at 23:06
  • 1
    Sorry about that, I'll take note for next time. – yann Aug 29 '15 at 23:09

1 Answers1

0

I think the most simple way is to check the type of every single document on it's saving. if you allow to save each doctype only once you will get only different doctypes for each user. In that case you do not need to use double filtering or whatever.

You can rewrite the save() method for each form in a formset by creating your CustomInlineFormSet. Here is the link: https://docs.djangoproject.com/en/1.8/topics/forms/modelforms/#overriding-methods-on-an-inlineformset.

It could be smth like this for example:

from django.forms.models import BaseInlineFormSet

class DocumentInlineFormSet(BaseInlineFormSet):
    def clean(self):
        super(DocumentInlineFormSet, self).clean()
        for form in self.forms:
            document = form.save(commit=False)
            #check your document here
            document.save()
chem1st
  • 1,624
  • 1
  • 16
  • 22
  • Thanks for answering. I was thinking about something like that to save it. But my problem is about displaying it. – yann Aug 30 '15 at 02:41
  • Are documents of all types required? Can one user have only one document of each type in db? If answer on both questions is yes, you can simply sort all documents by doctype and render a formset normally. On saving the formset you can iterate all forms and check if there is a document of a desired type uploaded (the order of doctypes you know). Remember that document of any type is still a document, so you need to load all docs in standard DocumentInlineFormSet, not to have separate forms for each doctype. – chem1st Aug 30 '15 at 07:58
  • Moreover, if you want to add some labels of placeholders specific for all types, you can render a formset manually: [link](https://docs.djangoproject.com/en/1.8/topics/forms/formsets/) – chem1st Aug 30 '15 at 08:05
  • Yes document of all types (document_type) are required, but only when "utilisation_type"= "USER" so I need to filter what field to display. And yes, one user can only have one document of each type in db. My point is that I dont see how to code the display formset, that iterate on "document_type" filtred on "utilisation_type"= "USER" to, at the end, display only one button for each "document_type" and nothing more. – yann Aug 30 '15 at 11:32
  • Why do you want to iterate formset on "document_type"? It is complicated, from my point of view. Filter documents by "utilisation_type" and render them all in your template. Inform user about the desired doctype in each form with custom labels and/or placeholders, check the type of uploaded docs (or do whatever you want) on saving and allow only one document of each type. To update the existing docs for a user, simply sort them by doctype to know their order, and validate one by one using cycle `{% for form in formset %}` – chem1st Aug 30 '15 at 20:34