Save files via upload to the folder configured with the stipulated name

Asked

Viewed 88 times

0

I am in development environment, and would like to record an image by placing it after upload in a folder that I have configured locally on my machine like this:

MEDIA_URL = '/media/'

MEDIA_ROOT = '.. /Static/media/'

The problem is two:

1º Image does not go to the folder I created and gave write permission

2º The file name, I would like it to contain the id of the instance "instance.id". When I submit form, the field in the table receives a name like this: "2019-07-25_085029.207286.None.Roupeiro.jpeg" where the date and time are as I would like, and only the id next to the name would serve to not have any problem overwriting the file in the folder, for information purposes I can leave with the date, what this wrong is the Name.

models.py

from django.db import models
from qnow_user.models import User
from django.conf import settings
from datetime import datetime,date
from django.contrib.auth import get_user_model

User = get_user_model()

def user_directory_path(instance, filename):
    return "%s.%s.%s" %(datetime.now(), instance.id, filename)

#Mobile type descripton
class MobilieType(models.Model):
    description = models.CharField(max_length=50,blank=False,unique=True)

    def __str__(self):
        return self.description

class Quotation(models.Model):
    #Quotation number
    id = models.AutoField(primary_key=True)

    #Quotation owner
    client = models.ForeignKey(settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE, default=User, related_name='quotation')    

    #Quotation cration date
    date_create = models.DateField(default=date.today)

    #Quotation update date
    date_update = models.DateField(default=date.today)

    #House type for quotation
    HOUSETYPECHOICES = (
    ('Apartamento', 'Apartamento'),
    ('Casa', 'Casa'),
    ('Comercial', 'Comercial'),
    ('Escritório', 'Escritório'),
    ('Outro', 'Outro'),
    )
    house_type = models.CharField('Tipo de imóvel para cotação?',max_length=20,
        choices=HOUSETYPECHOICES,blank=False,default='Casa',
        help_text='Nos informe o tipo do seu imóvel(Apartamento, casa...)')

    STATUSCHOICES = (
        (0,'Pendente'),   #Client requested quotation
        (1,'Em Análise'), #Company analizing quotation
        (2,'Liberado'),   #Quotation released for provider
        (3,'Orçado'),     #Quotation provider
    )
    status = models.IntegerField(choices=STATUSCHOICES, blank=False,default=0)

    #House set to quotation                
    house_set = models.CharField(max_length=100,default='Digite aqui!')

    #Mobile type 
    mobile_type = models.ForeignKey(MobilieType,on_delete=True,related_name='MobileType')

    #Mobile description to others  
    mobile_description = models.CharField(max_length=100,blank=False,default='Encontrei na lista acima!')

    #Mobile of particulars
    particulars  = models.TextField(blank=False)

    image_photo = models.FileField(upload_to=user_directory_path)

    class Meta:
        verbose_name = 'Cotação'
        verbose_name_plural = 'Cotações'

    def __str__(self):
        return str(self.client)


views.py

from django.shortcuts import render, redirect
from django.shortcuts import get_list_or_404, get_object_or_404
from django.contrib.auth.decorators import login_required
from django.contrib.auth import authenticate, login
from .models import Quotation
from .forms import QuotationForm

@login_required
def quotation_client(request):
    template_name = '../templates/client_quotation.html'
    form = QuotationForm(request.POST or None, request.FILES or None)
    if request.method == 'POST':
        if request.user.is_authenticated:
            Quotation = form.save(commit=False)
            Quotation.client = request.user
            if form.is_valid():
                form.save(commit=True)
                return redirect('qnow_site:site')
            else:
                form = QuotationForm()
        else:
            context = {
                'origin':'client',
                'active_page_client_provider':'active'
            }
            return redirect('qnow_user:login_client_start')
    else:
        form = QuotationForm()
    context = {
                'active_page_client_provider' : 'active',
                'form':form
                }
    return render(request,template_name,context)


1 answer

0

1. Image does not go to the folder I created and have given write permission

In the documentation of settings.MEDIA_ROOT speaking:

Absolute filesystem path to the directory that will hold user-uploaded files.

That is, it is specified that the path must be absolute and you are using a relative path in your configuration.

You can use the variable BASE_DIR defined at the beginning of settings.py as a starting point, use os.path.join and os.path.abspath to take the absolute path of the folder. Ex.:

MEDIA_ROOT = os.path.abspath(os.path.join(BASE_DIR, '../static'))

2. ID is None when naming file

If you look at the documentation of FileField.upload_to you will find that in the part where you explain the argument instance has the paragraph:

In Most cases, this Object will not have been saved to the database yet, so if it uses the default Autofield, it Might not yet have a value for its Primary key field.

Free translation:

In most cases, the object has not yet been saved to the database, so if Model uses default Autofield, it may not yet have set value for the primary key.

That is, when its function is executed the model has not yet been saved in the database, so id is None.

  • About MEDIA_ROOT, I’ll fix it and we’ll see what happens. Now about the ID, you’re right, I understood this by analyzing the code. Ok but how do I have a unique value in the image name to ensure that it does not overwrite a uploaded image?

  • You could save the model without the image and insert it later, that way you would already have the ID. You could also use some type of counter and separate the images by folders, etc... Then it will depend on how you will want to do.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.