Django create a file upload form with version control and save output to model

In my last articles, I spoke about creating a login for an app in Django and creating a file upload form in Django. In this article, I am going to share with you what project I am working on and some enhancements to that upload form I have made.

The project I am working on is a code repository. A user can login, create a project (e.g. MySuperWebsite) and can upload all of their code files to that project. When they have an update, they can come back and upload again to that project & it will automatically version control it.

So how does that work. Well, let’s look. In the below views.py, we receive the POST data from the form. That data includes the actual form response and the files that have been attached to it.

We then create a directory structure which will be appname/media/upload/username/projectname/version. We say ‘does version 1 exist?’ if it does, we check for version 2 and so on. When we find a version number that doesn’t exist, we create a directory of that version and save the files there. We the save it by creating an object in the projects model.

def upload_file(request):
    if request.method == 'POST':
        form = UploadFileForm(request.POST, request.FILES)
        zz = 0
        x = request.POST.get('title')
        if zz < 10:
            title = request.POST.get('title')
     
            version = 1
            exists = 0
            while exists == 0:
                filepath = 'rrls/media/upload/' + str(title) + '/' + str(version) + '/'
                if os.path.exists(filepath) == False:
                    exists = 1
                else:
                    version = version + 1
           
            version = str(version) 
            filepath = 'rrls/media/upload/' + str(title) + '/' + str(version) + '/'
            for file in request.FILES.getlist('file_field'):
                
                chunks = []
                
                if not os.path.exists(filepath):
                    os.makedirs(filepath)
                
                i =  projects.objects.create(project_name=title, current_version=int(version))
                with open(filepath + str(file), 'wb+') as destination:  
                    for chunk in file.chunks():
                        chunks.append(chunk)
                        destination.write(chunk)
        else:
            title = 'invalid form'
            print(form.errors)
    return render(request, 'index.html', {'x':x})

Now, you may be asking, how that works, because, if a user types ProjectName today and projectname tomorrow, then it would be 2 separate directories. Yes, so I populate the possible list of projects from the projects model itself. Below, you can see how that is done.

from django import forms
from .models import *
class UploadFileForm(forms.Form):
    title = forms.ModelChoiceField(queryset=projects.objects.values_list('project_name', flat=True))
    file_field = forms.FileField(widget=forms.ClearableFileInput(attrs={'multiple': True}))

Now, let’s look at the model. It’s all pretty self explanatory, but what is that return self.project_name? Well, that is the name that will appear in the admin panel. Instead of the default project object (n) we will have our own title displayed there.

class projects(models.Model):
    project_name = models.CharField(max_length=400, default="none")
    current_version = models.IntegerField()
    description = models.CharField(max_length=400, default="none")
    def __str__(self):
        return self.project_name, self.current_version