Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
511 views
in Technique[技术] by (71.8m points)

python - Django how to customize upload_to function

I created a system with Django. In this system a user has more than one customers. There is a customer list. A user can upload files to a customer's page. What I want to is the file should save in a file and path of this file should be customer_customername (For example: customer_Emily). But in my code created a file that name as customer_None. How can i fix it? file upload model and customer model are 2 different models that connecetd with a foreign key owner

Pdf/models.py

def customer_directory_path(instance, filename):
    return 'customer_{0}/{1}'.format(instance.id, filename)


class Pdf(models.Model):
    CHOICES = [
        ...
    ]

    STAT = [
        ...

    ]

    id = models.AutoField(primary_key=True)
    title = models.CharField(max_length=200)
    pdf = models.FileField(upload_to=customer_directory_path)
    owner = models.ForeignKey(Customer, on_delete=models.CASCADE, null=True)

customer/models.py

class Customer(models.Model):

    customer_name = models.CharField(max_length=20)
    ...

    id = models.AutoField(primary_key=True)

views.py

def pdf_list(request,id):
    customer = get_object_or_404(Customer, id=id)
    pdfs = Pdf.objects.filter(owner=customer)
    return render(request, 'pdf_list.html', {'pdfs': pdfs})
def upload_pdf(request,id):
    if request.method == 'POST':
        customer = get_object_or_404(Customer, id=id)
        form = PdfForm(request.POST, request.FILES)

        if form.is_valid():
            new_pdf=form.save()
            new_pdf.owner = customer
            new_pdf.save()
            return redirect('pdf_list',id)
    else:
        form = PdfForm()

    return render(request, 'upload_pdf.html', {'form': form})

forms.py

class PdfForm(forms.ModelForm):
    INTEGER_CHOICES = [tuple([year, year]) for year in range(2015, datetime.now().year + 1)]
    year = forms.IntegerField(widget=forms.Select(choices=INTEGER_CHOICES))


    class Meta:
        model = Pdf
        fields = ['title', 'pdf', 'type', 'year']

Note: When I change .format(instance.id, filename) as .format(instance.owner.customer_name, filename) there is an error:

AttributeError at /pdfs/analyses/ 'NoneType' object has no attribute 'customer_name'

traceback

Environment:


Request Method: POST
Request URL: http://127.0.0.1:8000/pdfs/12/upload/

Django Version: 3.1.4
Python Version: 3.8.7
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'register',
 'customer',
 'financial_analysis',
 'ocr',
 'crispy_forms',
 'ckeditor']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback (most recent call last):

      File "C:UsersUSEROneDriveDocumentsGitHubotcmyvenvlibsite-packagesdjangocorehandlersexception.py", line 47, in inner
        response = get_response(request)
      File "C:UsersUSEROneDriveDocumentsGitHubotcmyvenvlibsite-packagesdjangocorehandlersase.py", line 179, in _get_response
        response = wrapped_callback(request, *callback_args, **callback_kwargs)
      File "C:UsersUSEROneDriveDocumentsGitHubotcfinancial_analysisviews.py", line 24, in upload_pdf
        new_pdf=form.save()
      File "C:UsersUSEROneDriveDocumentsGitHubotcmyvenvlibsite-packagesdjangoformsmodels.py", line 460, in save
        self.instance.save()
      File "C:UsersUSEROneDriveDocumentsGitHubotcmyvenvlibsite-packagesdjangodbmodelsase.py", line 753, in save
        self.save_base(using=using, force_insert=force_insert,
      File "C:UsersUSEROneDriveDocumentsGitHubotcmyvenvlibsite-packagesdjangodbmodelsase.py", line 790, in save_base
        updated = self._save_table(
      File "C:UsersUSEROneDriveDocumentsGitHubotcmyvenvlibsite-packagesdjangodbmodelsase.py", line 895, in _save_table
        results = self._do_insert(cls._base_manager, using, fields, returning_fields, raw)
      File "C:UsersUSEROneDriveDocumentsGitHubotcmyvenvlibsite-packagesdjangodbmodelsase.py", line 933, in _do_insert
        return manager._insert(
      File "C:UsersUSEROneDriveDocumentsGitHubotcmyvenvlibsite-packagesdjangodbmodelsmanager.py", line 85, in manager_method
        return getattr(self.get_queryset(), name)(*args, **kwargs)
      File "C:UsersUSEROneDriveDocumentsGitHubotcmyvenvlibsite-packagesdjangodbmodelsquery.py", line 1254, in _insert
        return query.get_compiler(using=using).execute_sql(returning_fields)
      File "C:UsersUSEROneDriveDocumentsGitHubotcmyvenvlibsite-packagesdjangodbmodelssqlcompiler.py", line 1396, in execute_sql
        for sql, params in self.as_sql():
      File "C:UsersUSEROneDriveDocumentsGitHubotcmyvenvlibsite-packagesdjangodbmodelssqlcompiler.py", line 1339, in as_sql
        value_rows = [
      File "C:UsersUSEROneDriveDocumentsGitHubotcmyvenvlibsite-packagesdjangodbmodelssqlcompiler.py", line 1340, in <listcomp>
        [self.prepare_value(field, self.pre_save_val(field, obj)) for field in fields]
      File "C:UsersUSEROneDriveDocumentsGitHubotcmyvenvlibsite-packagesdjangodbmodelssqlcompiler.py", line 1340, in <listcomp>
        [self.prepare_value(field, self.pre_save_val(field, obj)) for field in fields]
      File "C:UsersUSEROneDriveDocumentsGitHubotcmyvenvlibsite-packagesdjangodbmodelssqlcompiler.py", line 1291, in pre_save_val
        return field.pre_save(obj, add=True)
      File "C:UsersUSEROneDriveDocumentsGitHubotcmyvenvlibsite-packagesdjangodbmodelsfieldsfiles.py", line 307, in pre_save
        file.save(file.name, file.file, save=False)
      File "C:UsersUSEROneDriveDocumentsGitHubotcmyvenvlibsite-packagesdjangodbmodelsfieldsfiles.py", line 86, in save
        name = self.field.generate_filename(self.instance, name)
      File "C:UsersUSEROneDriveDocumentsGitHubotcmyvenvlibsite-packagesdjangodbmodelsfieldsfiles.py", line 322, in generate_filename
        filename = self.upload_to(instance, filename)
      File "C:UsersUSEROneDriveDocumentsGitHubotcfinancial_analysismodels.py", line 10, in customer_directory_path
        return 'customer_{0}/{1}'.format(self.owner.customer_name, filename)
    
    Exception Type: AttributeError at /pdfs/12/upload/
    Exception Value: 'NoneType' object has no attribute 'customer_name'

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Try changing:

new_pdf = form.save()

To this:

new_pdf = form.save(commit=False)

As you have not provided the owner then to the model object, you should not commit the object there. After specifying the owner, the owner will not be None any longer, therefore the code will work as intended.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...