Local variable 'contacts_data' referenced before assignment - python-3.x

When I trying to call the method POST, it successfully creates, but I get the error's message in my serializers. What I should do, to get success when I call this method in my RESTful API?
Serializers.py:
def create(self, validated_data):
if 'branches' in validated_data:
branches_data = validated_data.pop('branches')
if 'contacts' in validated_data:
contacts_data = validated_data.pop('contacts')
course = Course.objects.create(**validated_data)
branches_list = []
contacts_list = []
print(contacts_data)
print(branches_data)
for branches_details in branches_data:
branches_list.append(Branch.objects.create(
course_id = course.id,
**branches_details))
for contacts_details in contacts_data:
contacts_list.append(Contact.objects.create(
course_id = course.id,
**contacts_details))
course.save()
return course

I will assume that branches_data and contacts_data are lists, so in case they are not present, they should be declared as empty lists. The following code will run:
def create(self, validated_data):
branches_data = validated_data.pop('branches') if 'branches' in validated_data else []
contacts_data = validated_data.pop('contacts') if 'contacts' in validated_data else []
course = Course.objects.create(**validated_data)
branches_list = []
contacts_list = []
print(contacts_data)
print(branches_data)
for branches_details in branches_data:
branches_list.append(Branch.objects.create(
course_id = course.id,
**branches_details))
for contacts_details in contacts_data:
contacts_list.append(Contact.objects.create(
course_id = course.id,
**contacts_details))
course.save()
return course

Related

how to work with foreign key field in django

Hi Everyone i am working work django framework, where i used to upload excel file in Dailytrip table, current i get car_mumber from car table, but now i need to store car_number from Car_team table also team_id, i am storing car_id and team_id in car_team table also i need to store team_id in dailytrip table automaticlly based on car_id(car_number) i am to much confuse how to i work that, pls help me out
models.py
class Car_team(BaseModel):
team = models.ForeignKey(
Team,
models.CASCADE,
verbose_name='Team',
null=True,
)
car=models.ForeignKey(
Car,
models.CASCADE,
verbose_name='Car',
null=True)
city =models.ForeignKey(
City,
models.CASCADE,
verbose_name='City',
)
start_date=models.DateField(null=True, blank=True)
end_date=models.DateField(null=True, blank=True)
views.py
def add_payout_uber_daily_data(request):
if request.method == 'POST':
form = UberPerformanceDataForm(request.POST, request.FILES, request=request)
if form.is_valid():
date = form.cleaned_data['date']
excel_file = request.FILES['file']
df = pd.read_excel(excel_file)
is_na = pd.isna(df['Date']).sum().sum() + pd.isna(df['Name']).sum().sum() + pd.isna(df['UUID']).sum().sum() + pd.isna(df['Net Fare With Toll']).sum().sum() + pd.isna(df['Trips']).sum().sum() + pd.isna(df['Uber KMs']).sum().sum() + pd.isna(df['CashCollected']).sum().sum() + pd.isna(df['UberToll']).sum().sum() + pd.isna(df['Tips']).sum().sum() + pd.isna(df['Hours Online']).sum().sum() + pd.isna(df['Ratings']).sum().sum() + pd.isna(df['Acceptance Rate']).sum().sum() + pd.isna(df['Cancellation Rate']).sum().sum()
error_list = []
if is_na > 0:
error_list.append('Found #N/A or blank values in the sheet. Please correct and re-upload')
context = {'error_list': error_list, 'menu_payout': 'active','submenu_daily_data': 'active','form': form, }
return render(request, 'add_payout_uber_daily_data.html', context=context)
date_match = True
for d in df['Date']:
if str(d.strftime("%Y-%m-%d")) != str(date):
date_match = False
break
if not date_match:
error_list.append('Some dates are not matching in excel')
if len(error_list) > 0:
context = {'error_list': error_list, 'menu_payout': 'active','submenu_daily_data': 'active','form': form, }
return render(request, 'add_payout_uber_daily_data.html', context=context)
DailyTrip.objects.filter(date=date).update(is_active=0)
for i in df.index:
uuid = df['UUID'][i]
driver_id = None
car_id = None
fleet_id = None
manager_id = None
try:
driver = Driver.objects.get(uber_uuid=uuid)
driver_id = driver.id
except Driver.DoesNotExist:
driver_id = None
#replce car code and store car_number,car_id,team_id via car_team only this logic need to change current get car_number direct car table but we need car_number vai foriegn key
try:
car = Car.objects.get(car_number=df["Car Number"][i])
car_id = car.id
manager_id = car.manager_id
except Car.DoesNotExist:
car_id = None
try:
fleet = Fleet.objects.get(name=df["Fleet Name"][i])
fleet_id = fleet.id
except Fleet.DoesNotExist:
fleet_id = None
name = df['Name'][i]
car_number = df['Car Number'][i]
fare_total = df['Net Fare With Toll'][i]
trips = df['Trips'][i]
pool_trips = 0
hours_online = df['Hours Online'][i]
total_km = df['Uber KMs'][i]
cash_collected = abs(df['CashCollected'][i])
toll = df['UberToll'][i]
tip_amount = df['Tips'][i]
fare_avg = float(fare_total)/int(trips)
fare_per_hour_online = float(fare_total)/float(hours_online)
fare_per_km = fare_total/total_km
trips_per_hour = trips/hours_online
km_per_trip = total_km/trips
rating = df['Ratings'][i]
acceptance_rate_perc = float(df['Acceptance Rate'][i])/100
driver_cancellation_rate = float(df['Cancellation Rate'][i])/100
obj, created = DailyTrip.all_objects.update_or_create(
date=date, uuid=uuid,
defaults={
'car_id': car_id,
'manager_id': manager_id,
'car_number': car_number,
'driver_id': driver_id,
'car_id': car_id,
'fleet_id': fleet_id,
'driver_name': name,
'fare_total': fare_total,
'trips': trips,
'pool_trips': pool_trips,
'hours_online': hours_online,
'total_km': total_km,
'cash_collected': cash_collected,
'toll': toll,
'tip_amount': tip_amount,
'fare_avg': fare_avg,
'fare_per_hour_online':fare_per_hour_online,
'fare_per_km':fare_per_km,
'trips_per_hour': trips_per_hour,
'km_per_trip': km_per_trip,
'rating': rating,
'acceptance_rate_perc': acceptance_rate_perc,
'driver_cancellation_rate': driver_cancellation_rate,
'is_active': 1,
'comments': None}
)
if len(error_list) > 0:
DailyTrip.objects.filter(date=date).update(is_active=0)
context = {'error_list': error_list, 'menu_payout': 'active','submenu_daily_data': 'active','form': form, }
return render(request, 'add_payout_uber_daily_data.html', context=context)
else:
messages.success(request, 'Daily Trips added Successfully...')
return redirect('/fleet/payout/daily_data/add/uber')
else:
form = UberPerformanceDataForm(initial={})
context = {
'menu_payout': 'active',
'submenu_daily_data': 'active',
'form': form,
}
return render(request, 'add_payout_uber_daily_data.html', context=context)
You can try that :
to get car_number from car_team -->
car_team = car_team.objects.objects.all().last() # to get the last car_team for example
car_number = car_team.car.car_number # to get the car number from the car_team
try:
car = Car.objects.get(car_number=df["Car Number"][i])
car_id = car.id
car1=Car_team.objects.filter(car_id=car_id)
if car1:
team_id=car1[0].team_id
else:
team_id=None
except Car.DoesNotExist:
car_id = None
team_id= None

UnboundLocalError: local variable 'date_pool_async_results' referenced before assignment

The following returns a list of the desired payload in a PDF for a single site:
import multiprocessing as mp
def process_dates(dates, serviceAreaId, serviceAreaName, siteId, siteName):
model_results = []
# for loop to process dates
return model_results
def process_service_area(site):
pdf_results = []
siteId = site["id"]
siteName = site["name"]
siteTimeZone = site["time_zone"]
service_area_response = requests.request("GET",f"{lrs_url}/serviceAreas/active?siteId={siteId}", headers={},data={})
if service_area_response.status_code != 200:
sendMessageToSlack(f"Failed to retrieve service areas for site {siteId}.")
return pdf_results
service_area_json_response = json.loads(service_area_response.content)
tz = timezone(siteTimeZone)
startdate = datetime.now(tz)
dates = pd.date_range(start=startdate, periods=7).to_pydatetime().tolist()
date_pool = mp.Pool(mp.cpu_count())
for service_area in service_area_json_response:
serviceAreaName = service_area["name"]
serviceAreaId = service_area["id"]
active = service_area["active"]
#Run comparison
date_pool_async_results = date_pool.apply_async(process_dates, args = (dates, serviceAreaId, serviceAreaName, siteId, siteName))
date_pool.close()
date_pool.join()
for r in date_pool_async_results.get():
pdf_results.append(r)
return pdf_results
def process_all_sites():
sites_response = requests.request("GET",f"{lrs_url}/sites/active", headers={}, data={})
sites_json_response = json.loads(sites_response.content)
pdf_results = []
for site in sites_json_response:
pdf_results += process_service_area(site)
break
# service_area_pool = mp.Pool(2)
# service_area_pool_async_results = #service_area_pool.apply_async(process_service_area, args = (site))
# service_area_pool.close()
# service_area_pool.join()
# for r in service_area_pool_async_results.get():
# pdf_results.append(r)
return pdf_results
results = process_all_sites()
create_pdf(results)
However, when the script is ran for multiple sites, that is, when break is commented and service_area_pool up to pdf_results.append(r) are uncommented, I receive an UnboundLocalError: local variable 'date_pool_async_results' referenced before assignment
Why is that the case? It seems that date_pool_async_results does not receive any further payloads than just the first iteration.
I've gone through these following resources; however, they don't seem to work as as solution as I am trying to append to a list in my case.
I've also tried the following, but received an UnboundLocalError: local variable 'pdf_results' referenced before assignment as well.
global pdf_results
pdf_results = []
def process_all_sites():
# retrieve payload
Please do let me know if further context is required.

bad performance for loop with instance and bulk create

I need to use bulk_create to create a lot of "detalle"(details), the problem is i have to iterate trough a json to get the arguments, and i got 4 fk so django ask to me for the instance, not the id. but to have id i have to do a .get(), so i got a bad performance, because its 4 gets by each iteration.
its there a way to get all objects instances and put in a list or something to perform load then the instance without using get every time?
class DetalleFichaAllViewSet(viewsets.ModelViewSet):
serializer_class = DetalleFichaUpdateAllSerializer
def create(self, request, *args, **kwargs):
user = self.request.user
data = request.data
try:
ficha = Ficha.objects.get(autor=user.id)
DetalleFicha.objects.filter(ficha=ficha.id).delete()
except Http404:
pass
# Create Ficha
now = datetime.now()
date_time = now.strftime("%Y-%m-%d %H:%M")
print("AAAAAA DATA:", data)
Ficha.objects.filter(autor=user.id).update(fecha_creacion=date_time, autor=user,
nombre=data["nombreFicha"], descripcion=data["descripcionFicha"])
ficha = Ficha.objects.filter(autor=user.id).last()
recintos = Recinto.objects.all()
productos = Producto.objects.all()
estandar_productos = EstandarProducto.objects.all()
cotizaciones = Cotizacion.objects.all()
detalles_ficha = []
for detalle in data["detalles"]:
recinto = recintos.get(id=detalle[1])
producto = productos.get(id=detalle[10])
estandar_producto = estandar_productos.get(id=detalle[9])
try:
cotizacion = cotizaciones.get(id=detalle[4])
except ObjectDoesNotExist:
cotizacion = None
print("Fecha: ", detalle[8])
detalle = DetalleFicha(carreras=detalle[0],
recinto=recinto, nombre=detalle[2],
cantidad_a_comprar=detalle[3], cotizacion=cotizacion,
valor_unitario=detalle[5], valor_total=detalle[6],
documento=detalle[7], fecha_cotizacion=detalle[8],
estandar_producto=estandar_producto, producto=producto,
ficha=ficha)
detalles_ficha.append(detalle)
DetalleFicha.objects.bulk_create(detalles_ficha)
print("Array convertida", detalles_ficha)
print(detalles_ficha[0])
return Response(status=status.HTTP_200_OK)

Dictionary with functions versus dictionary with class

I'm creating a game where i have the data imported from a database, but i have a little problem...
Currently i get a copy of the data as a dictionary, which i need to pass as argument to my GUI, however i also need to process some data, like in this example:
I get the data as a dict (I've created the UseDatabase context manager and is working):
def get_user(name: str, passwd: str):
user = {}
user['name'] = name
user['passwd'] = passwd
with UseDatabase() as cursor:
_SQL = "SELECT id, cash, ruby FROM user WHERE name='Admin' AND password='adminpass'"
cursor.execute(_SQL)
res = cursor.fetchall()
if res:
user['id'] = res[0][0]
user['cash'] = res[0][1]
user['ruby'] = res[0][2]
return user
return res
.
.
.
def get_activities():
with UseDatabase() as cursor:
_SQL = "SELECT * FROM activities WHERE user_id='2'"
cursor.execute(_SQL)
res = cursor.fetchall()
if res:
ids = [i[0] for i in res]
activities = {}
for i in res:
activities[i[0]] = {'title':i[1],'unlock':i[2],'usr_progress':i[3]}
return (ids, activities)
return res
Need it as a dict in my GUI ("content" argument):
class SideBar:
def __init__(self, screen: 'pygame.display.set_mode()', box_width: int, box_height: int, content: dict, font: 'font = pygame.font.Font()'):
#content dict: {id: {'title':'','unlock':'','usr_progress':''},...}
self.box_width = box_width
self.box_height = box_height
self.box_per_screen = screen.get_height() // box_height
self.content = content
self.current_box = 1
self.screen = screen
self.font = font
self.generate_bar()
def generate_bar (self):
active = [i for i in self.content.keys() if i in range(self.current_box, self.current_box+self.box_per_screen)]
for i in range(self.box_per_screen):
gfxdraw.box(self.screen,pygame.Rect((0,i*self.box_height),(self.screen.get_width()/3,self.screen.get_height()/3)),(249,0,0,170))
self.screen.blit(self.font.render(str(active[i]) + ' - ' + self.content[active[i]]['title'], True, (255,255,255)),(10,i*self.box_height+4))
for i in range(self.box_per_screen):
pygame.draw.rect(self.screen,(50,0,0),pygame.Rect((0,i*self.box_height),(self.screen.get_width()/3,self.screen.get_height()/3)),2)
But still need to make some changes in the data:
def unlock_act(act_id):
if user['cash'] >= activities[act_id]['unlock'] and activities[act_id]['usr_progress'] == 0:
user['cash'] -= activities[act_id]['unlock']
activities[act_id]['usr_progress'] = 1
So the question is: in this situation should i keep a copy of the data as dict, and create a class with it plus the methods i need or use functions to edit the data inside the dict?

ValueError: Unknown protobuf attr type <class 'dict'> when tried to put a nested dict/entity

I tried to put a nested entity/dict into datastore using Python,
metadata_row = dict()
metadata_row['batch_id'] = str(uuid1())
metadata_row['table_ok'] = True
metadata_row['table_name'] = 'metadata'
metadata_row['num_rows'] = 1
metadata_row['violations'] = []
metadata_row['errors'] = []
metadata_row['time'] = {}
metadata_row['time']['total_time'] = 82.42656564712524
metadata_row['time']['mod1'] = 5.940682411193848
metadata_row['time']['mod2'] = 19.16786551475525
metadata_row['time']['mod3'] = 31.617812633514404
metadata_row['time']['mod4'] = 0.00038933753967285156
metadata_row['time']['mod5'] = 53.35780310630798
with self.client.transaction():
entities = [Entity(self.client.key('metadata')) for i in range(len([metadata_row]))]
for entity, update_dict in zip(entities, [metadata_row]):
entity.update(update_dict)
self.client.put_multi(entities)
I tested it by using datastore emulator, but I got the following error,
ValueError: Unknown protobuf attr type <class 'dict'>
I am wondering how to fix the issue. I am also wondering does datastore natively support nested dictionary in that one doesn't have to create an entity for the inner dictionary, i.e. time in this case.
UPDATE. I added an inner entity in metadata_row for key time to solve the problem.
client = datastore.Client()
metadata_row['time'] = datastore.Entity(key=client.key('time'))
metadata_row['time']['total_time'] = 82.42656564712524
metadata_row['time']['mod1'] = 5.940682411193848
metadata_row['time']['mod2'] = 19.16786551475525
metadata_row['time']['mod3'] = 31.617812633514404
metadata_row['time']['mod4'] = 0.00038933753967285156
metadata_row['time']['mod5'] = 53.35780310630798
# code for put_multi()
def convert(obj, client, key):
"""
:param obj: dict
:param client: datastore client
:param key: Generated as client.key("your_table", "your_key")
:return: datastore.Entity
"""
if isinstance(obj, list):
return [convert(item, client, None) for item in obj]
elif isinstance(obj, dict):
entity = datastore.Entity(key)
for key in obj:
entity[key] = convert(obj[key], client, None)
return entity
else:
return obj
Please do suggest any improvements or alternatives as Google Cloud Datastore currently doesn't suggest a way to convert a JSON to an Entity.

Resources