Jim Jim - 1 month ago 16
Python Question

Django KeyError when trying to format foreignkey

I'm getting the following error when trying to create a filepath

filepath = '{comp}/utils/locndb/{vehdir}.{filename}'.format(comp,vehdir, filename)
KeyError: 'comp'


I don't know how to extract the string from a one-to-many foreignkey field

extra.py

def get_file_path(vehicle, filename):

filepath = ''

vehdir = vehicle.vehid
print vehdir
comp = getattr(vehicle.company, 'user', None)
print comp

filepath = 'optiload/{comp}/utils/locndb/{vehdir}.{filename}'.format(comp,vehdir, filename)
print filepath

return filepath


views.py

@login_required
def loadlocndb(request):


if request.method == "POST" and request.FILES['locndb']:
pks = request.POST.getlist("update")

selected_objects = Vehicle.objects.filter(pk__in=pks)

vlist = []
for i in selected_objects:
vlist.append(i)
locnfile = request.FILES['locndb']
fs = FileSystemStorage()
filename = fs.save(locnfile.name, locnfile)
filename = get_file_path(i, filename)
uploaded_file_url = fs.url(filename)

return render(request, 'portal/loadlocndb.html',{"vlist":vlist, "uploaded_file_url": uploaded_file_url})


models.py

# Create your models here.
class UserProfile(models.Model):
# This line is required. Links UserProfile to a User model instance.
user = models.OneToOneField(User)

# The additional attributes we wish to include.
compName = models.CharField(max_length = 20)
milkco = models.IntegerField()


# Override the __unicode__() method to return out something meaningful!
def __unicode__(self):
return self.user.username

class Vehicle(models.Model):
vehid = models.CharField(max_length = 10)
company = models.ForeignKey(UserProfile, default = 1)
#depot = models.ForeignKey(Depot, default = 1)
locndb = models.FileField(upload_to='optload/', default= "setting.MEDIA_ROOT/locndb/LocnDB.csv")

class Meta:
db_table = "vehicle"

def __unicode__(self):
return self.vehid


I want to import and save a file to the filepath
/optiload/{customer}/utils/locndb/{vehicle}/{filename}
is there a better way to do it than how I am currently?

Answer

The problem is that your string contains named arguments (e.g. {comp}), but you are using positional arguments when you call format()

You can either remove the names from the braces in your string:

filepath = '{}/utils/locndb/{}.{}'.format(comp, vehdir, filename)

or use keyword arguments when calling format:

filepath = '{comp}/utils/locndb/{vehdir}.{filename}'.format(comp=comp, vehdir=vehdir, filename=filename)