Conditioning without if - Django python - python

I want to choose one thing or the other but I can't use an if statement since an error occurs even if i just try it.
How can i structure the code so that if possible, I do this:
i = Image(entry = e,\
image = request.FILES['file'],))
i.save()
and if it wasn't possible, I should do this instead:
i = Image(entry = e,\
url = request.POST['website'])
i.save()
The basic thing I'm actually checking is if i can call request.FILES, since my image is either just a URL or a local file itself, but I can't try it in an if statement.
Thank you

Simple solution:
kw = {'entry': e}
if 'file' in request.FILES:
kw['image'] = request.FILES['file']
elif 'url' in request.POST:
kw['url'] = request.POST['website']
else:
raise SomeException()
i = Image(**kw)
i.save()
but you'd be better using a Form or ModelForm with custom validation...

try:
i = Image(entry = e,\
image = request.FILES['file'],))
i.save()
except:
i = Image(entry = e,\
url = request.POST['website'])
i.save()

Related

Django ORM create rows dynamically with _meta.get_fields()

I am writing a function to read xlsx and write this data to the database with Django. But I have so many fields that I cannot define statically. I want to write these fields to the database with a certain algorithm. When designing this, I get the class attributes with _meta.get_fields(). But as seen in this example, attributes always remain None. In views.py there is an example between BEGIN and END codes. How can i solve this problem?
views.py
# ... some codes ...
#login_required(login_url='/admin/login/')
def import_process(request):
if request.method == 'POST':
form = UploadFileForm(request.POST, request.FILES)
if form.is_valid():
file_in_memory = request.FILES['file'].read()
wb = load_workbook(filename=BytesIO(file_in_memory), data_only=True)
ws = wb.worksheets[0]
ws_company_name = str(ws["D9"].value)
ws_company_address = str(ws["D10"].value)
# ... some codes ...
# Company Tower Get ID loop
company_staff = CompanyStaff.objects.filter(company_id=Company.objects.filter(company_name=ws_company_name)[0].id)[0]
for col in COLUMN_PARAMETER_LIST:
column_cell = str(col) + str(COLUMN_PARAMETER_BEGIN)
ws_tower_type = str(ws[column_cell].value)
tower_type = TowerType.objects.filter(tower_type=ws_tower_type)[0]
c_tower_object = CompanyTower.objects.filter(company_staff_id=company_staff,tower_type_id=tower_type)[0]
tower_data = TowerData.objects.create(company_tower_id=c_tower_object)
ROW_IDX = int(ROW_PARAMETER_BEGIN-1)
# ****************** BEGIN ****************** #
site_fields = tower_data._meta.get_fields()
site_fields_names = [f.name for f in site_fields][1:]
for mfield in site_fields_names:
if any(word in str(mfield) for word in TOWER_DATA_EXCLUDE_FIELDS_NEW):
continue
else:
ROW_IDX += 1
tower_data_cell = str(col)+str(ROW_IDX)
tower_data_cell_value = ws[tower_data_cell].value
tower_data.mfield = tower_data_cell_value
if str(mfield) == 'ph': # Example Field
print(tower_data.mfield)
print(tower_data.ph)
# ******************* END ******************* #
tower_data.save()
print("****************")
return render(request, template_name='import.html',context={"form": UploadFileForm()})
# ... some codes ...
You're currently setting and replacing an attribute called mfield over and over: tower_data.mfield = tower_data_cell_value.
What you want is setattr(tower_data, mfield, tower_data_cell_value)

Django 2 different error: "local variable referenced before assignment" + "The view didn't return an HttpResponse object. It returned None instead. "

I try to render this view for a Django project and i can get out from these two errors.
The first one is "local variable 'list_of_data' referenced before the assignment. After I change the scope of that variable I get another error "The view didn't return an HttpResponse object. It returned None instead."
I tried a few solutions founded around on the web but i couldn't resolve them.
Here is the views code:
def forecast(request):
if request.method == 'POST':
city = urllib.parse.quote_plus(request.POST['city'])
source = urllib.request.urlopen('http://api.openweathermap.org/data/2.5/weather?q='+ city +'&units=metric&appid=API_KEY').read()
list_of_data = json.loads(source)
day = datetime.datetime.today()
today_date = int(day.strftime('%d'))
forcast_data_list = {} # dictionary to store json data
#looping to get value and put it in the dictionary
for c in range(0, list_of_data['cnt']):
date_var1 = list_of_data['list'][c]['dt_txt']
date_time_obj1 = datetime.datetime.strptime(date_var1, '%Y-%m-%d %H:%M:%S')
if int(date_time_obj1.strftime('%d')) == today_date or int(date_time_obj1.strftime('%d')) == today_date+1:
# print(date_time_obj1.strftime('%d %a'))
if int(date_time_obj1.strftime('%d')) == today_date+1:
today_date += 1
forcast_data_list[today_date] = {}
forcast_data_list[today_date]['day'] = date_time_obj1.strftime('%A')
forcast_data_list[today_date]['date'] = date_time_obj1.strftime('%d %b, %Y')
forcast_data_list[today_date]['time'] = date_time_obj1.strftime('%I:%M %p')
forcast_data_list[today_date]['FeelsLike'] = list_of_data['list'][c]['main']['feels_like']
forcast_data_list[today_date]['temperature'] = list_of_data['list'][c]['main']['temp']
forcast_data_list[today_date]['temperature_max'] = list_of_data['list'][c]['main']['temp_max']
forcast_data_list[today_date]['temperature_min'] = list_of_data['list'][c]['main']['temp_min']
forcast_data_list[today_date]['description'] = list_of_data['list'][c]['weather'][0]['description']
forcast_data_list[today_date]['icon'] = list_of_data['list'][c]['weather'][0]['icon']
today_date += 1
else:
pass
#returning the context with all the data to the forecast.html
context = {
'forcast_data_list':forcast_data_list
}
return render(request, 'forecast.html', context)
If i run this view i get the "local data referenced before assignment" error.
PS: For some reason the first time it works...
Thanks for any help.
If the request.method is not a POST, list_of_data never gets defined because of the if statement. Define list_of_date = [] outside of the if statement.

save to django database

Im trying too save info to an ArrayField by using append. According to this post it should be possible but i cant get it to work. Im not creating a new object, it already exists i just need to append additional info to the ArrayField
Code snippet:
def isInDatabase(catInfo):
cat = catagories.objects
catName = str(catInfo)
iban = catInfo.getIban()
try:
cat.get(Naam = catName)
except ObjectDoesNotExist:
print catName, 'is not in database'
# NOTE: create catagory
p = cat.create(Naam = catName, Rekening = [iban])
print catName, 'Has been stored in the database with', iban
else:
ibanList = cat.get(Naam = catName).Rekening
editCat = cat.get(Naam = catName)
print catName,'is in db, the following ibans are stored:\n\n', ibanList,'\n\n'
if iban in ibanList:
print iban,'is already in the list\n'
else:
ibanList.append(iban)
editCat.save()
print 'Updated list for',catName,'with -->',iban,'\nlist is now -->', ibanList,'\n'
the editCat.save() is the save command thats not saving.
models.py
class catagories(models.Model):
Naam = models.CharField(max_length=10)
Rekening = ArrayField(models.CharField(max_length = 34), blank = True)
def __str__(self):
return self.Naam
So what modifications do i need to make to get it to save it to the database. I don't get any error, so the script runs fine but it doesn't save to the database.
This is the problem code:
ibanList = cat.get(Naam = catName).Rekening
editCat = cat.get(Naam = catName)
...
ibanList.append(iban)
editCat.save()
The editCat remains unchanged. Use call to database only once and then get ibanList from the object you want to edit.
editCat = cat.get(Naam = catName)
ibanList = editCat.Rekening
When you initialize editCat with editCat = cat.get(Naam = catName), you actually create new variable, which is not associated with ibanList. What you need to do is to change already retrieved value. Possible solution could be
editCat = cat.get(Naam = catName)
editCat.Rekening.append(iban)
editCat.save()
Another issue that worth to be mentioned is the presence of redundant db calls. Everytime you call get, you actually make new request on db (to be precise when queryset is evaluated). It would be better to retrieve value from db only once and operate over it.

Python / Django - Local variable designed before assignment

I know this topic is talked many times in Stackoverflow but it concerns many different methods and I need help. I'm stuck since four hours ^^'
Here is the message : local variable 'menuItem' referenced before assignment
def B2BpartnerMenuDetailModify(request, partnerId, menuId, menuItemId):
message = ''
e = B2BpartnerUser(request, partnerId)
try:
menuDetail = Menu.objects.get(id=menuId)
except Menu.DoesNotExist:
return logoutUser(request)
if request.method == 'POST':
form = MenuDetailForm(request.POST, mySelf=partnerId)
if form.is_valid():
descrShort = form.cleaned_data['descrShort']
paragraph = form.cleaned_data['paragraph']
producteur = form.cleaned_data['producteur']
position = MenuItem.objects.filter(menuId = menuDetail).filter(paragraph = paragraph).count() + 1
menuItem = MenuItem(menuId = menuDetail)
menuItem.descrShort = descrShort
menuItem.paragraph = paragraph
menuItem.producteur = producteur
menuItem.save()
if producteur > 0:
menuItemProd = MenuItemProd(menuItemId = menuItem)
menuItemProd.entrepriseId = producteur
menuItemProd.save()
message = _('Details modified successfuly')
else:
data = {'descrShort': menuItem.descrShort, 'paragraph': menuItem.paragraph, 'producteur': menuItem.producteur}
form = MenuDetailForm(initial=data)
menuItems = MenuItem.objects.filter(menuId = menuDetail).select_related()
menus = Menu.objects.filter(entrepriseId=e)
menuParagraph = MenuParagraph.objects.filter(actif=1)
modifier = True
#detail = False
return render (request, 'front/B2Bmenu.html', {'MenuDetailForm': form, 'menus': menus, 'message': message, 'partnerId': partnerId, 'modifier': modifier, 'detail': detail, 'menuDetail': menuDetail, 'menuParagraph': menuParagraph, 'menuId': menuId, 'menuItems': menuItems})
I'm sure I can get my page when this error is resolved. I'm sure it's a little error, I'm a beginner at Python but I love the language :)
If you want I can give you more details but I don't think it's necessary ^^
Have a nice day and thank you for your help :)
I found it !
I just forgot to add another try for this variable, just after the first try.
try:
menuItem = MenuItem.objects.get(id=menuItemId)
except MenuItem.DoesNotExist:
return logoutUser(request)

I/O operation on closed file when saving a model

Hi guys i have my problem in this part in the code. I have multiple files uploaded from o global variable.
file_car = None # Global variable
and in my views.py
if request.method == 'POST':
if file_car is None:
print request.FILES
file_car = [request.FILES.get('dzfile[%d]' % i)
for i in range(0, len(request.FILES))]
I need to use like this because I need to use this images in a lot of other views. But the problem is when I want to save
for f in file_car:
print f
myfyle= File(f)
#myfyle.open()
aux = Attachment()
aux.name= f
aux.car = car
aux.save() # here is the error. I tried opening the file but it said you cannot reopen the file
It throw me I/O operation on closed file.I'm going crazy with this. Sorry for my bad english
Edit Here is a more compressive code if it helps
from django.core.files import File
def createCarView(request):
global file_car
if request.method == 'POST':
if file_car is None:
form = CarForm(request.POST, request.FILES) # other valus
print request.FILES # Print all the file that I get
file_car = [request.FILES.get('dzfile[%d]' % i)
for i in range(0, len(request.FILES))] # Have all the fileS!
if form.is_valid():
# omitted all the other part of the form!
car.save()
for f in file_car:
print f
#myfyle.open()
aux = Attachment()
aux.name=myfyle
aux.car = car
aux.save() #Error in here
print aux.name
file_car=None # cleaning the global var
return HttpResponseRedirect('/car/create')
models.py
class Attachment(models.Model):
car = models.ForeignKey('Car', on_delete=models.CASCADE)
name = models.FileField(_('File'),
upload_to=upload_to_get,
)
Code is not clear but error says you should open the file so how about trying something like this ? :
for f in file_car:
with open(f,"a") as f:
print f
myfyle= File(f)
aux = Attachment()
aux.name=myfyle
aux.car = car
aux.save()

Categories

Resources