Custom x-Axis name from different fields in django-chartit - python

I have model like
class MyModel(models.Model):
date = models.DateField()
type = models.CharField(max_length=10)
n_1 = models.IntegerField()
n_2 = models.IntegerField()
Date is unique and type is not.
I want to create chart with X-Axis labels like "Type (Date)" i.e. "FirstType (2014-10-02)", so I want to combine data from two model fields in axis label. Can you please advice me how can I do it?

It is not required to pass the model objects directly to chartit. You can transform them into dicts which then have the appropriate values:
data = [
{'label': "{0} ({1})".format(o.date, o.type), 'value': o.n_1}
for o in MyModel.objects.all()
]
See the documentation for the library you have chosen to use for more information.

Related

Streamlit problem for filtering a selectbox depending on another selectbox

I am trying to do a streamlit app in order to predict the price of a car depending on the values of some variables.
I would like to narrow the choice of model depending on the brand of the car. I did this code in order to have a list.
#create input dictionary and list for categorical variables :
#for the variable Make
make_unique = df['Make'].unique()
make_dict = dict(zip(make_unique, range(len(make_unique))))
make_list = list(make_dict.keys())
#for the variable Model
model_unique = df['Model'].unique()
model_dict = dict(zip(model_unique, range(len(model_unique))))
model_list = list(model_dict.keys())
Then I created a function to narrow the choice:
def filter_model(make):
model = df[df['Make'] == brand]['Model'].unique()
return list(model)
And I then created selectboxes:
#start taking inputs
brand_input = col1.selectbox("Select Brand", make_list, help = "From which brand the car is made")
brand = make_dict[brand_input]
# for the variable Model
model_input = col2.selectbox("Select Model", filter_model(brand_input), help = "From which model the car is made")
model = model_dict[model_input]
However it gives me this error:
model = model_dict[model_input]
KeyError: None
I think you can simplify your code and with unique and loc, and you don't need all these filter functions. I left the second one with multiselectm but it works with single select as well:
brand = st.selectbox(
'Select Brand',
df.make.unique())
model=st.multiselect('Select your model', df.loc[df.make==brand]['model'].unique())
p.s. i made it for my dataset, so please adjust column names, you have capitalized column names.

Django and chart.js - one bar per 'date' in model

I have a model that contains a date and a number. There are multiple inputs from the same date that I want to merge into 1 bar on the chart. How can I show each date only once but add up all of the totalPacks under that date?
model:
Views:
def homepage(request):
labels = []
data = []
queryset = DailyCountsModel.objects.order_by('-date')
for jobs in queryset:
labels.append(jobs.date)
data.append(jobs.totalPacks)
return render(request,'index.html', {
'labels': labels,
'data': data,
})
Currently this chart will show one bar per entry.. I can't think of how I could do this. Any ideas? I'm guessing somehow I would need to check to see how many items they are with the 'date' of 2021-08-23 and add up the 'totalPacks', I'm just not sure how I would do this
from django.db.models import Count
result = (DailyCountsModel.objects
.values('totalPacks', 'date')
.annotate(dcount=Count('totalPacks'))
.order_by('-date')
)

Django, how to extract values list monthly from DateField?

I have the following models:
class Materiale(models.Model):
sottocategoria = models.ForeignKey(Sottocategoria, on_delete=models.CASCADE, null=True)
quantita=models.DecimalField(')
prezzo=models.DecimalField()
data=models.DateField(default="GG/MM/YYYY")
I wanna calculate the value given by the following expressions PREZZO*QUANTIA in a monthly's view (in other words the total sum of PRZZO*QUANTITA of all items in a single month), but my code does not work:
Monthly_views=Materiale.objects.filter(data__year='2020').values_list('month').annotate(totale_mensile=F(('quantita')*F('prezzo')))
Use values() method instead of values_list()
from django.db.models import F, Sum
result = Materiale.objects.annotate(totale_mensile=F('quantita') * F('prezzo')
).values('data__month').annotate(totale_mensile_sum=Sum('totale_mensile')))
or simply
result = Materiale.objects.values('data__month').annotate(totale_mensile_sum=Sum(F('quantita') * F('prezzo')))
Try filtering by month also
Monthly_views=Materiale.objects.filter(data__year='2020').filter(data_month='4')

how to edit the form with data from the models

views.py
Editrow = KEBReading.objects.get(id=id)
print Editrow.datetime_reading
event_full_datetime=datetime(Editrow.datetime_reading.year,
Editrow.datetime_reading.month,
Editrow.datetime_reading.day,
Editrow.datetime_reading.hour,
Editrow.datetime_reading.minute,
Editrow.datetime_reading.second)
date = event_full_datetime.year, event_full_datetime.month, event_full_datetime.day
time = event_full_datetime.hour, event_full_datetime.minute
print date
print time
form = KEBReading_form(instance=Editrow)
in my models i have a datetime field. but in my forms i have a separate date and time field. but when i want to edit a row my variable Editrow has datetime value how do i populate the form with separate date and time while passing the instance(Editrow)
form = KEBReading_form(instance=Editrow)
First, you should understand how to use widgets for form fields. Then, just use SplitDateTimeWidget.

Converting Django QuerySet to pandas DataFrame

I am going to convert a Django QuerySet to a pandas DataFrame as follows:
qs = SomeModel.objects.select_related().filter(date__year=2012)
q = qs.values('date', 'OtherField')
df = pd.DataFrame.from_records(q)
It works, but is there a more efficient way?
import pandas as pd
import datetime
from myapp.models import BlogPost
df = pd.DataFrame(list(BlogPost.objects.all().values()))
df = pd.DataFrame(list(BlogPost.objects.filter(date__gte=datetime.datetime(2012, 5, 1)).values()))
# limit which fields
df = pd.DataFrame(list(BlogPost.objects.all().values('author', 'date', 'slug')))
The above is how I do the same thing. The most useful addition is specifying which fields you are interested in. If it's only a subset of the available fields you are interested in, then this would give a performance boost I imagine.
Convert the queryset on values_list() will be more memory efficient than on values() directly. Since the method values() returns a queryset of list of dict (key:value pairs), values_list() only returns list of tuple (pure data). It will save about 50% memory, just need to set the column information when you call pd.DataFrame().
Method 1:
queryset = models.xxx.objects.values("A","B","C","D")
df = pd.DataFrame(list(queryset)) ## consumes much memory
#df = pd.DataFrame.from_records(queryset) ## works but no much change on memory usage
Method 2:
queryset = models.xxx.objects.values_list("A","B","C","D")
df = pd.DataFrame(list(queryset), columns=["A","B","C","D"]) ## this will save 50% memory
#df = pd.DataFrame.from_records(queryset, columns=["A","B","C","D"]) ##It does not work. Crashed with datatype is queryset not list.
I tested this on my project with >1 million rows data, the peak memory is reduced from 2G to 1G.
Django Pandas solves this rather neatly: https://github.com/chrisdev/django-pandas/
From the README:
class MyModel(models.Model):
full_name = models.CharField(max_length=25)
age = models.IntegerField()
department = models.CharField(max_length=3)
wage = models.FloatField()
from django_pandas.io import read_frame
qs = MyModel.objects.all()
df = read_frame(qs)
From the Django perspective (I'm not familiar with pandas) this is fine. My only concern is that if you have a very large number of records, you may run into memory problems. If this were the case, something along the lines of this memory efficient queryset iterator would be necessary. (The snippet as written might require some rewriting to allow for your smart use of .values()).
You maybe can use model_to_dict
import datetime
from django.forms import model_to_dict
pallobjs = [ model_to_dict(pallobj) for pallobj in PalletsManag.objects.filter(estado='APTO_PARA_VENTA')]
df = pd.DataFrame(pallobjs)
df.head()

Categories

Resources