RknRobin RknRobin - 2 months ago 14
Python Question

Within Dango, how do I add a new value to request.POST data before saving?

I'm trying to allow the user to either manually enter a text field if they have the license info, or let it auto generate (based on form info) if its original content.

I'm stuck because from my tests (using print command) the form is correctly updating with the information given in the form if LicenseTag field is left blank. The issue is that the updated information is not being saved in the database. After research this seems to be an issue of immutability, which is why I added request.POST.copy() and tested the commented out section defining mutability=True.

Here's my views.py

def STLupload(request):
if request.method == 'POST':
form = NewUpload(request.POST, request.FILES)
data = request.POST.copy()

if form.is_valid():
#Dis gona need alot of work
firstname = request.user.first_name
lastname = request.user.last_name
displayname = request.user.display_name
email = request.user.email


if (firstname or lastname == "None"):
if displayname == "None":
liscname = email
else:
liscname = '%s %s' % (firstname, lastname)
else:
liscname = displayname


filetitle = request.POST.get(
'Title'
, '')


lisc = '%s %s' % (filetitle, liscname)

if data['LicenseTag'] == "":

'''
mutable = request.POST._mutable
request.POST._mutable = True
request.POST['LicenseTag'] = lisc
request.POST._mutable = mutable
'''

data['LicenseTag'] = lisc
print (request.POST.get(
'LicenseTag'
, ''))
print ("blank")
else:

print (form)


#Save current username
comment = form.save(commit=False)
comment.user = request.user

comment.save()

#Flash success message
messages.add_message(request, messages.SUCCESS, "File uploaded successful")

# Redirect to the document list after POST
return HttpResponseRedirect(reverse_lazy('STLup'))
else:
form = NewUpload() # A empty, unbound form


Can anyone help me figure out how to save the generated information into my database?

Edit #1

Models.py

from django.db import models

import os
#import django.db.models.deletion
from django.db import models
from django.core.exceptions import ValidationError
from django.core.files.storage import FileSystemStorage
from django.utils.translation import ugettext_lazy as _
from django.utils import timezone
from django.conf import settings

from django.contrib.auth.models import User


# Create your models here.

def user_directory_path(instance, filename):
# file will be uploaded to MEDIA_ROOT/user_<id>/<filename>
return os.path.join('uploads', str(instance.Title), filename)


def validate_file_extension(value):
ext = os.path.splitext(value.name)[1]
valid_extensions = ['.stl','.STL']
if not ext in valid_extensions:
raise ValidationError(u'Please upload a .stl file type only')

def validate_img_extension(value):
ext = os.path.splitext(value.name)[1]
valid_extensions = ['.jpg','.png','.JPG']
if not ext in valid_extensions:
raise ValidationError(u'Please upload a .jpg or .png only')

class UploadedFiles(models.Model):

user = models.ForeignKey(
settings.AUTH_USER_MODEL, blank=True, null=True)

STL = models.FileField(_('STL Upload'),
upload_to=user_directory_path, validators=[validate_file_extension])
Photo = models.ImageField(_('Photo'),
upload_to=user_directory_path, validators=[validate_img_extension])

Title = models.CharField(_('Title of object'),
max_length=40, blank=False, null=True, unique=False)
Category = models.CharField(_('Category'),
max_length=40, blank=False, null=True, unique=False)
SubCategory = models.CharField(_('SubCategory'),
max_length=40, blank=True, null=True, unique=False)
SubSubCategory = models.CharField(_('*SubSubCategory (optional)'),
max_length=40, blank=True, null=True, unique=False)

FileType = models.BooleanField(_('Local?'),
default=0, unique=False)

Description = models.TextField(_('File Description'),
max_length=200, blank=True, null=True, unique=False)
LicenseTag = models.CharField(_('*License (optional, leave blank for original content)'),
max_length=200, blank=True, null=True, unique=False)


Xdim_mm = models.IntegerField(_('X dimension (mm)'),
default=0)
Ydim_mm = models.IntegerField(_('Y dimension (mm)'),
default=0)
Zdim_mm = models.IntegerField(_('Z dimension (mm)'),
default=0)

pub_date = models.DateTimeField(_('date_joined'), default=timezone.now)


Here is my forms.py.

from django import forms
from django.core.validators import MinLengthValidator

from .models import UploadedFiles


class NewUpload(forms.ModelForm):


class Meta:
model = UploadedFiles
fields = ('Title', 'STL','Photo','Description', 'Category', 'SubCategory', 'SubSubCategory', 'LicenseTag')

Answer

As I see it the best way is to override the save method in your model.

class UploadedFiles(models.Model):
    def save(self, *args, **kwargs):
        if not self.LicenseTag:
            if self.user:
                liscname = self.user.get_full_name() or self.user.email
                self.LicenseTag = "{0} {1}".format(liscname, self.Title)

        super(UploadFiles,self).save(*args,**kwargs)

Then the same thing works in your admin without having to do a lot of hard work. I have taken the liberty to optimize how the license tag is derived.

Now your view becomes a whole lot simpler.

def STLupload(request):
    if request.method == 'POST':
        form = NewUpload(request.POST, request.FILES)
        if form.is_valid():
            lisc = '%s %s' % (filetitle, liscname)

            #Save current username
            comment = form.save(commit=False)
            comment.user = request.user

            comment.save()

            #Flash success message
            messages.add_message(request, messages.SUCCESS, "File uploaded successful")    

            # Redirect to the document list after POST
            return HttpResponseRedirect(reverse_lazy('STLup'))
    else:
        form = NewUpload()  # A empty, unbound form