Hi I'm trying to get the newest/latest number in a query set:
I use this codeline for that:
CartQuantity.objects.filter(customer=customer).values_list('cquantity', flat=True).get(pk=-1)
This is how the queryset looks like:
<bound method QuerySet.last of <QuerySet [4, 4, 4, 2, 4, 4, 5, 6, 5, 14, 10, 12]>> # need last number(12)
I tried the code above but I get an Error message:
store.models.CartQuantity.DoesNotExist: CartQuantity matching query does not exist.
This is my models:
class CartQuantity(models.Model):
customer = models.ForeignKey(Customer, on_delete=models.SET_NULL, blank=True, null=True)
cquantity = models.IntegerField(default=0, null=True, blank=True)
Does anyone know how to fix the error or another way of getting the newest number(in this case number 12 in the query set)?
CartQuantity.objects.filter(customer=customer).values_list('cquantity', flat=True)[-1]
or
CartQuantity.objects.filter(customer=customer).values_list('cquantity', flat=True).last()
or
CartQuantity.objects.filter(customer=customer).values_list('cquantity', flat=True).reverse()[0]
Related
I am currently trying to save a Django object. My code looks like this
boxscore = BoxScore.objects.create(**defaults)
print(defaults)
input(boxscore)
Here's the output:
{'away_first': 0, 'away_second': 6, 'away_third': 7, 'away_fourth': 17, 'away_final': 30, 'home_first': 0, 'home_second': 7, 'home_third': 0, 'home_fourth': 7, 'home_final': 14}
BoxScore object (190)
Here's my admin:
#admin.register(BoxScore)
class BoxScoreAdmin(ImportExportModelAdmin):
pass
Here's the model:
class BoxScore(Base):
home_final = models.IntegerField()
away_final = models.IntegerField()
home_first = models.IntegerField()
away_first = models.IntegerField()
home_second = models.IntegerField()
away_second = models.IntegerField()
home_third = models.IntegerField()
away_third = models.IntegerField()
home_fourth = models.IntegerField()
away_fourth = models.IntegerField()
home_ot = models.IntegerField(null=True)
away_ot = models.IntegerField(null=True)
Here's the whole helper function if that is relevant.
def create_boxscore(df):
defaults = {
'away_first': int(df.at[0, '1']),
'away_second': int(df.at[0, '2']),
'away_third': int(df.at[0, '3']),
'away_fourth': int(df.at[0, '4']),
'away_final': int(df.at[0, 'Final']),
'home_first': int(df.at[1, '1']),
'home_second': int(df.at[1, '2']),
'home_third': int(df.at[1, '3']),
'home_fourth': int(df.at[1, '4']),
'home_final': int(df.at[1, 'Final']),
}
try:
defaults['home_ot'] = int(df.at[1, 'OT'])
defaults['away_ot'] = int(df.at[0, 'OT'])
except:
pass
boxscore = BoxScore(**defaults)
boxscore.save()
return boxscore
However, nothing is showing in Django admin as being saved in the database. Why would this be and how do I fix it?
Update: I queried the database and confirmed nothing is being saved so it is not a Django admin display issue.
Update 2: If I run the sample above separately, it saves fine. However, if it is run within a helper function, nothing saves. Does being in a helper function cause saving difficulties?
Update 3: In the main function, I ran this line of code and nothing was saved:
if 'Final' in dfs[i].columns and '4' in dfs[i].columns:
defaults = {'away_first': 0, 'away_second': 6, 'away_third': 7,
'away_fourth': 17, 'away_final': 30, 'home_first': 0, 'home_second': 7,
'home_third': 0, 'home_fourth': 7, 'home_final': 14}
boxscore = BoxScore.objects.create(**defaults)
input(boxscore)
But this was still outputted so I know it's reaching that line of code:
BoxScore object (200)
I'm actually using python 3.7 and Django 3.0.4.
I using in my app models.py like this for a simple system of messages.
from torii.models import User
class Room(models.Model):
users = models.ManyToManyField(User,
related_name='rooms',
blank=True)
name = models.CharField(max_length=100)
class Message(models.Model):
room = models.ForeignKey(Room,
on_delete=models.CASCADE,
related_name='messages')
user = models.ForeignKey(User,
on_delete=models.CASCADE)
content = models.TextField()
date = models.DateTimeField(auto_now_add=True)
So when my user send a message I create a new Message object attached to my Room.
I want to query all Room for a given User and annotate the date of the most recent message and the last message in my query.
No problem to get the most recent date in my related messages using Max like this:
for room in Room.objects.filter(users=user).annotate(last_message_date=Max('messages__date')).order_by('-last_message_date'):
print(room.__dict__)
{'id': 7, 'name': 'room-7', 'last_message_date': datetime.datetime(2020, 3, 20, 14, 0, 2, 118190, tzinfo=<UTC>)}
{'id': 9, 'name': 'room-9', 'last_message_date': datetime.datetime(2020, 3, 8, 15, 19, 52, 343780, tzinfo=<UTC>)}
{'id': 8, 'name': 'room-8', 'last_message_date': datetime.datetime(2020, 3, 7, 17, 18, 32, 648093, tzinfo=<UTC>)}
But I don't find any way to simply annotate the content of the last message. I have tried Max('messages__content') but in fact, it's order message by alphabetic order and it's always the same who is returned... I tried several subqueries with F and Q but that it didn’t work very well.
How can I annotate the result of room.messages.last().content directly with my query?
Finally, I solve this problem using OuterRef and Subquery documented there.
from django.db.models import Max, OuterRef, Subquery
newest = Message.objects.filter(room_id=OuterRef('pk')).order_by('-date')
for room in Room.objects.filter(users=user)
.annotate(last_message_date=Max('messages__date'),
last_message=Subquery(newest.values('content')[:1]))
.order_by('-last_message_date'):
print(r.__dict__)
As I understand the behavior, we prepare beforehand Subquery by saying to use id of the element who call the subquery to annotate the filtred elements and order then by -date. So it returns the most recent element and we take the value of field content to annotate it.
This will create a complex but unique request using all the performance of the database.
Inside of models I have:
The Hotel Name
The price for each night.
models.py:
class Hotel_Database(models.Model):
hotel_name = models.CharField(max_length=20)
class Hotel_Date_Price(models.Model):
hotel = models.ForeignKey(Hotel_Database, on_delete=models.CASCADE , related_name='hotel')
checkin = models.DateField(default= datetime.date.today())
checkout = models.DateField(default=datetime.date.today() + datetime.timedelta(1))
price = models.IntegerField()
views.py:
import datetime
x = Hotel_Database.objects.get(id=1)
#the price for the night of June 26th:
Hotel_Date_Price.objects.create(hotel = x, checkin= datetime.date(2018, 6, 27), checkout=datetime.date(2018, 6,28), price=50).save()
#the price for the night of June 27th:
Hotel_Date_Price.objects.create(hotel = x, checkin= datetime.date(2018, 6, 28), checkout=datetime.date(2018, 6,29), price=50).save()
Hotel_Database.objects.filter(hotel_name__icontains='Hotel', hotel__checkin__lte=datetime.date(2018, 6, 27), hotel__checkout__gte=datetime.date(2018, 6, 28))
#results: <QuerySet [<Hotel_Database: Shangri-La>]>
Now here is what happens when I try to filter through more than one night:
Hotel_Database.objects.filter(hotel_name__icontains='Hotel', hotel__checkin__lte=datetime.date(2018, 6, 27), hotel__checkout__gte=datetime.date(2018, 6, 29))
#results: <QuerySet []>
# it returns an empty list
I am basically trying to change the price of each night
Looks like you confused lte and gte. lte means less than, while gte is greater than. So you should use end date with lte condition and start date with gte:
Hotel_Database.objects.filter(hotel_name__icontains='Hotel', hotel__checkin__gte=datetime.date(2018, 6, 27), hotel__checkout__lte=datetime.date(2018, 6, 29))
Also note you don't need to call save() after create() method. You can just use create().
UPD
If you need to exclude hotels with specific period of checkin/checkout from queryset you can use exclude():
Hotel_Database.objects.filter(hotel_name__icontains='Hotel').exclude( hotel__checkin__gte=datetime.date(2018, 6, 27), hotel__checkout__lte=datetime.date(2018, 6, 29))
I have a model that represents a rubric, and each rubric has multiple rows. For some reason, I run the query below, and I receive an incomplete queryset. The variable semesterrubric is a queryset of rubrics that has already been evaluated in the code and returns the correct rubric models.
"""
semesterrubric pulls both Rubric 1 and Rubric 2
Rubric 1:
Row: 2 Row:4
Rubric 2:
Row: 1 Row : 1
"""
Row.objects.filter(rubric=semesterrubric)
<QuerySet [<Row: 2>, <Row: 4>]>
I know it's incomplete because when I iterate over the semesterrubric queryset object and pull the rows from each individual rubric, I receive two querysets with the rows that I need.
[rubric.row_set.all() for rubric in semesterrubric]
[<QuerySet [<Row: 2>, <Row: 4>]>, <QuerySet [<Row: 1>, <Row: 1>]>]
I would like to have a single query that returns all of the rows. What am I missing? I've read (most of) the documentation on querysets, but it is possible I missed something.
models.py
class Rubric(models.Model):
name = models.TextField(default="Basic Rubric", unique=True)
template = models.BooleanField(default=True)
def __str__(self):
return self.name
class Row(models.Model):
CHOICES = (
('0', 'Your string for display'),
('4','Exemplary'),
('3','Proficient'),
('2','Partially Proficient'),
('1','Incomplete'),
)
name = models.CharField(default="None", max_length=100)
rubric = models.ForeignKey(Rubric)
row_choice = models.CharField(max_length=20,choices=CHOICES, default="0")
excellenttext = models.TextField(default="", blank=True)
proficienttext = models.TextField(default="", blank=True)
satisfactorytext = models.TextField(default="", blank=True)
unsatisfactorytext = models.TextField(default="", blank=True)
standards = models.ManyToManyField(Standard)
def __str__(self):
return self.row_choice
I'd not recommend on passing a queryset like this. try:
Row.objects.filter(rubric__in=semesterrubric.all())
You received two querysets because your semesterrubric has two elements inside. Try Row.objects.filter(rubric__in=semesterrubric)
This should solve your problem
Using django model with Foreignkey as follows:
class Types_of_Expenditures(models.Model):
Expenditure_owner = models.CharField(default="None",max_length=50)
Expenditure_Type = models.CharField(default="Miscellaneous",max_length=50)
Expenditure_Type_Description = models.CharField(max_length=200)
def __unicode__(self):
return self.Expenditure_Type
class Expenditure(models.Model):
exp_owner= models.CharField(default='None',max_length=50)
exp_date = models.DateTimeField("Expenditure_Date")
description = models.CharField(max_length=1000)
amount = models.FloatField(default=0)
currency = models.CharField(max_length=15,default="MYR",editable=True)
exp_pocket = models.ForeignKey(Pockets, null=True, blank=True)
exp_type = models.ForeignKey(Types_of_Expenditures)
class Meta:
unique_together = ('exp_date', 'description',)
def __unicode__(self):
return self.description
Now when i save data in Types of expenditure i am doing :
Types_of_Expenditures.objects.get_or_create(Expenditure_owner='a',Expenditure_Type_Description="Default one")
and in database data is as :
id Expenditure_owner Expenditure_Type Expenditure_type_description
1 a Miscellaneous default one
but when i add anything to Expenditure data is saved with data in exp_type as 1 but it should be Miscellaneous because in def unicode i am returning Expenditure_type .
Here s how i am using formset to save data for Expenditure model:
ExpFormSet = modelformset_factory(Expenditure,extra=10,max_num=10,
fields=('exp_date', 'description','exp_type','amount','currency','exp_pocket'),
can_delete=False,form=ExpenditureForm)
if request.method == 'POST':
formset = ExpFormSet(request.POST,queryset=Expenditure.objects.filter(exp_owner=request.user))
if formset.is_valid():
print "printing formset",formset
formset.save(commit=True)
cd = form.cleaned_data
expenditureType = cd.get('exp_type')
print "Expenditure Type entered is ",expenditureType
return index(request)
What i am doing in index view:
Expenditure_list = Expenditure.objects.order_by('-exp_date').filter(exp_owner=request.user)
print "Expenditure List is : ", Expenditure_list.values_list()
Now output of this expenditure view as value of Expenditure_list.values_list() is (please see last value which is 1 i.e. value of exp_type ) :
Expenditure List is : [(3, u'a', datetime.datetime(2014, 9, 12, 15, 32, 10), u'test', 1.0, u'MYR', u'pocket', 1)]
What do i expect :
Expenditure List is : [(3, u'a', datetime.datetime(2014, 9, 12, 15, 32, 10), u'test', 1.0, u'MYR', u'pocket', u'Miscellaneous')]
Can anyone help what could be the problem here ?
I feel This question might be wrong may be it will save only foreign key there i.e. id and in order to get expenditure type i need to retrieve it using Types_of_Expenditure.objects.get(pk="Key as in list")
but not sure if there s an alternate way ?
I think I understand your question. You seem to be expecting values_list to return the __unicode__ of a related model, but there's no reason to think it would: as the name implies, it returns the values only, and the value of a ForeignKey field is just the ID.
You can supply a list of fieldnames to values_list and traverse the relationship there, if you want:
Expenditure.objects.values_list('description', 'amount', 'exp_type__ Expenditure_Type')