I know this subject was discussed here, but I really can't get this to work... :(
I have this DeviceLocation model:
class DeviceLocation(models.Model):
device = models.ForeignKey(Device, related_name='locations', null=True, on_delete=models.SET_NULL)
device_imei = models.CharField(max_length=20)
user = models.ForeignKey(User, related_name='device_locations', null=True, on_delete=models.SET_NULL)
user_username = models.CharField(max_length=30, null=True)
timestamp = models.DateTimeField()
latitude = models.FloatField()
longitude = models.FloatField()
accuracy = models.FloatField()
speed = models.FloatField()
I want to get the last location for each different device, in the last 5 min. So I tried this:
time_now = datetime.now()
time_from = time_now.replace(minute=time_now.minute - 5)
last_device_locations = DeviceLocation.objects.filter(timestamp__range=(time_from, time_now)).distinct('device')
The thing is, distinct is not working... Return multiple results for the same device.
I searched the site and found a work-around using values, even so I can't do it:
DeviceLocation.objects.filter(timestamp__range=(time_from, time_now)).values('device', 'timestamp').order_by('device').distinct('device')
but this still doesn't work... :(
Any hints?
Thank you!
Can you try this:
DeviceLocation.objects.filter(timestamp__range=(time_from, time_now)).order_by('device', '-timestamp').distinct('device')
I'm not sure, but it may be that the .values() call is interacting with the select distinct.
Also, you want to add '-timestamp' to the .order_by() call, to make sure that you get the most recent location for each device.
Related
I have a model which acts a as schedule where there are multiple FK relationships to the same user table. All of these fields can be blank/null.
The issue is, when i do a for loop, i am trying to match the users based on when they appear on a certain shift, then add a +1 to a counter to get the total shifts for that user.
The model looks like this:
class WeekdayAssignment(models.Model):
"""Model definition for WeekdayAssignment."""
start_date = models.DateField(auto_now=False, auto_now_add=False)
end_date = models.DateField(auto_now=False, auto_now_add=False)
triage_emea_1 = models.ForeignKey(TeamMember, on_delete=models.DO_NOTHING, related_name="triage_emea_1", blank=True, null=True)
triage_nam_1 = models.ForeignKey(TeamMember, on_delete=models.DO_NOTHING, related_name="triage_nam_1", blank=True, null=True)
triage_nam_2 = models.ForeignKey(TeamMember, on_delete=models.DO_NOTHING, related_name="triage_nam_2", blank=True, null=True)
triage_nam_3 = models.ForeignKey(TeamMember, on_delete=models.DO_NOTHING, related_name="triage_nam_3", blank=True, null=True)
...
As you can see i have 4 triage shifts and the same user can work any of those shifts.
I want to do a for loop to count how many times a user is on a shift in any one of those fields.
Without getting into all the details of what I am doing, i will keep it simple as the error happens right away.
Views.py
def someview(request):
shift_users = TeamMember.objects.all()
weekday_shifts = WeekdayAssignment.objects.all()
for t in shift_users:
for ws in weekday_shifts:
print(ws.triage_nam_3)
As long as there is a value in the field, this will print fine but if the field is empty (i.e. no users selected for that field) it fails with TeamMember matching query does not exist.
I have tried to do check if None but it gives the same problem. Now this error goes away once I populate a user but how can i check if it's empty and just skip it?
Thanks in advance.
You can catch models.DoesNotExist exception.
def someview(request):
shift_users = TeamMember.objects.all()
weekday_shifts = WeekdayAssignment.objects.all()
for t in shift_users:
for ws in weekday_shifts:
try:
print(ws.triage_nam_3)
except TeamMember.DoesNotExist:
continue
I would like to do a lot of analysis/performance/statistics on my stock portfolio, which I plan to track with my app. E.g.:
Week performance
Month performance
Year performance
Best performer
and a lot of other things I can't imagine right now...
Where I'm struggling right now:
- What is a good/the best way to archive this? - Also to show this info on a dashboard
--> I think I should store this information somehow... But how to do this on a daily/weekly/whatever basis?
--> I don't see a way to do such things while runtime?
--> furthermore I need to know, when do do such thinks... It's end of the week so do weekly performance calculations...
--> Maybe there is also an MVP solution, that can evolve into a top-notch solution?
My models are locking like this at the moment - The position is the clamp around my orders and my EOD data. Right now I'm working with yfinance to get range financial data + finnhub API to get real time prices:
class Position(models.Model):
name = models.CharField(max_length=100)
shares = models.FloatField(default=0.0)
symbol = models.CharField(max_length=100, default="")
transaction_fee_sum = models.FloatField(default=0.0)
profit = models.FloatField(default=0.0)
average_price = models.FloatField(default=0.0)
cost_value = models.FloatField(default=0.0)
last_price = models.FloatField(default=0.0)
position_value = models.FloatField(default=0.0)
last_update = models.DateTimeField(default=datetime.now(), blank=True)
position_started = models.DateTimeField(default=datetime.now(), blank=True)
position_ended = models.DateTimeField(default=datetime.now(), blank=True)
isin = models.CharField(max_length=12)
depot = models.ForeignKey("Depot", blank=True, null=True, on_delete=models.SET_NULL)
def __str__(self):
return self.name
class PriceHistoryEOD(models.Model):
price = models.DecimalField(max_digits=8, decimal_places=2)
position = models.ForeignKey("Position", blank=True, null=True, on_delete=models.CASCADE)
price_date = models.DateField(default=date.today)
class Inventory_Position(models.Model):
shares = models.FloatField(default=0.0)
price = models.FloatField(default=0.0)
position = models.ForeignKey("Position", blank=True, null=True, on_delete=models.CASCADE)
def __str__(self):
return str(self.position.name) + "_Inventory_" + str(self.id)
class Order(models.Model):
ORDER_PLACES = (
('TRADEGATE', 'Tradegate'),
('FRANKFURT', 'Frankfurt'),
('STUTTGART', 'Stuttgart'),
)
ORDER_TYPE = (
('buy', 'buy'),
('sell', 'sell'),
)
name = models.CharField(max_length=100)
depot = models.ForeignKey("Depot", blank=True, null=True, on_delete=models.SET_NULL)
position = models.ForeignKey("Position", blank=True, null=True, on_delete=models.SET_NULL)
ko_identifier = models.BooleanField()
order_price = models.FloatField()
quantity = models.FloatField()
order_value = models.FloatField()
order_fees = models.DecimalField(decimal_places=2,max_digits=5,default=0.0, null=True)
order_date = models.DateTimeField('order date')
order_wkn = models.CharField(max_length=6)
order_isin = models.CharField(max_length=12)
order_TYPE = models.CharField(max_length=100, choices=ORDER_TYPE)
order_place = models.CharField(max_length=100, choices=ORDER_PLACES)
def __str__(self):
return self.name
I think the easiest way is to create a simple script for each type of analysis you need to do (weekly, monthly...) and then save the values to an sqlite3 DB. You can then import it into your django View as the data context. If you'd like to automate the whole process you can just set up a cronjob through crontab if you're using Linux, and if you're on Windows you can use the Windows task scheduler
Sqlite3 and python: How to work with sqlite3 and Python
If you are not familiar with crontab you can check out one of the many video on Youtube. As for the schedule expressions you can use this website, it makes it so much easier to find the expression you're looking for: https://crontab.guru/
finally one more tip, if you need to get stock prices and you feel like yfinance is kind of slow, you might want to try the Alpaca-trade-API (free API-KEY): https://github.com/alpacahq/alpaca-trade-api-python
I am fairly new to Django, but I am working on an application that will follow a CPQ flow or Configure, Price, Quote. The user should select the product they would like to configure as well as the options to go with it. Once selected, the program should query an external pricing database to calculate price. From there the program should output the pricing & text data onto a PDF quote. I was able to get the application working using the specific product inheriting from a base product class. The issue is now that I've created a second product child class, I cannot use a singular "related_name". I've omitted the lists associated with the drop down fields to help with readability, but I've posted my models.py file below.
Is there a way I can iterate through Product objects that are pointing to a Quote object with a foreign key? A lot of answers I've found on SO relating to this were able to be solved either by specifying the "_set" or "related_name". I've seen other answers use the select_related() method, however, I can't seem to get the query right as the program won't know which set it needs to look at. A quote could have any mix of product instances tied to it, so am unsure how to handle that query. Again, I have been using django under 6 months, so I am a bit green. I am not sure if I am just not fundamentally understanding the big picture here. I thought about instead of using inheritance, to make Product a standalone class and to save the Compact or WRC info to it so I could just use one "related_name", but also thought that would just create another nested layer that would still fail.
Any help would be very appreciated! I've definitely hit the wall.
models.py
class Quote(models.Model):
project_name = models.CharField(max_length=256,blank=True)
customer_first_name = models.CharField(max_length=256,blank=True)
customer_last_name = models.CharField(max_length=256,blank=True)
company_name = models.CharField(max_length=256, blank=True)
address1 = models.CharField(max_length=256, blank=True, help_text ="Address")
address2 = models.CharField(max_length=256, blank=True)
city = models.CharField(max_length=256, blank=True, default="")
state = models.CharField(max_length=256, blank=True, default="")
zip_code = models.CharField(max_length=256, blank=True, default="")
country = models.CharField(max_length=256, blank=True, default="")
phone = PhoneField(blank=True)
email = models.EmailField(max_length=254,blank=True)
grand_total = models.FloatField(default=0)
create_date = models.DateTimeField(default = timezone.now)
class Product(models.Model):
class Meta:
abstract = True
price = models.FloatField(default=0)
total_price = models.FloatField(default=0)
quantity = models.IntegerField()
quote = models.ForeignKey('quote.Quote', on_delete=models.CASCADE)
quantity = models.IntegerField()
class Compact(Product):
base_size = models.CharField(choices=size, max_length = 256)
filter = models.CharField(choices=filter_list, max_length = 256)
product_name = models.CharField(max_length=256,default="Compact")
class WRC(Product):
base_size = models.CharField(choices=size, max_length = 256)
construction = models.CharField(choices=construction_list, max_length = 256)
outlet = models.CharField(choices=outlet_list, max_length = 256)
product_name = models.CharField(max_length=256,default="WRC")
I was able to figure out my issue, but wanted to answer in case someone came across a similar problem as myself. I was able to get get all product objects attached to a quote instance dynamically by modifying the get_context_data() method of my QuoteDetailView. I also needed to use the django library NestedObjects from django.contrib.admin.utils to grab all related objects to the quote instance. I also added a timestamp field to the Product class to be able to sort them. QuoteDetailView copied below.
class QuoteDetailView(FormMixin,DetailView):
model = Quote
form_class = ProductSelectForm
def get_context_data(self, **kwargs):
### collects related objects from quote
collector = NestedObjects(using=DEFAULT_DB_ALIAS)
collector.collect([kwargs['object']])
### slice off first element which is the quote itself
related_objects = collector.nested()
related_objects = related_objects[1:]
### get context data for qoute object
context = super().get_context_data(**kwargs)
context['now'] = timezone.now()
### if number of list items is above 0, then add them to the context
### and sort by timestamp
if len(related_objects) != 0:
context['items'] = sorted(related_objects[0], key=lambda x: x.timestamp)
return context
I am extremely new to Django and kinda new to python and programming in general, so i may be asking a dumb question. I am trying to track medications in our inventory at work. Here is my model for the inventory in our safe
class Safe(models.Model):
user = models.ForeignKey(User, on_delete=models.PROTECT)
date_created = models.DateTimeField(auto_now=True)
drug_name = models.ForeignKey('components.Drug', related_name='drug_remove', on_delete=models.PROTECT, default=0)
amount_removed = models.IntegerField(blank=True, null=True)
amount_added = models.IntegerField(blank=True, null=True)
incident_number = models.CharField(max_length=20, default=0, blank=True)
patient_name = models.CharField(max_length=20, default=0, blank=True)
medic_unit = models.ForeignKey('components.MedicUnit', related_name='medic_unit', on_delete=models.PROTECT, blank=True)
free_text = models.CharField(max_length=1000, default=0, blank =True)
drug_total = computed_property.ComputedIntegerField(compute_from='add_drug')
I would like to store the medication total for each drug in the database. I understand from researching this that storing totals isn't best practice in most cases but I believe this is one exception. Obviously the calculated integer field isn't the answer, but none of my research has gotten me any closer to the answer. My guess is that I first need to filter by 'drug_name' and then calculate the added or subtracted drugs from the previous total in a function within my model. Thanks ahead of time for any help.
I might be getting wrongly what you need. But it seems to me that you just need to compute the drug_total + drug_added - drug_removed is that correct?
Add this to the bottom of your model:
def get_current_amount_of_drug(self):
return self.drug_total - self.drug_removed + self.drug_added
Then from any view or other place where you need it - you can just call
safe = Safe.objects.filter(drug_name="My Drug").first() # or however you filter them and then just get
safe.get_current_amount_of_drug()
Maybe the documentation would help you more:
https://docs.djangoproject.com/en/2.2/topics/db/models/#model-methods
I have two fields in my model.py one has multi choice drop down and one that is empty. What I would like to have is that if the user select "Gas" from the menu for type, I would like the amount field to get auto populated with distance * 2
Can I do that?
CHOICE = (
('Meal', 'Meal'),
('Gas', 'Gas'),
)
type = models.CharField(max_length=10, choices=CHOICE)
distance = models.CharField(max_length=100)
amount = models.CharField(max_length=100)
Thanks in advance.
You can use the django-observer app for this. Although there are cleaner Javascript approaches, you can make the automation totally depend on Django.
First, modify the amount field as:
amount = models.CharField(max_length=100, blank=True, null=True)
since it won't take any values when the model object is initially saved to the database. Then the rest of the code will look something like:
from observer.decorators import watch
def compute_amount(sender, obj, attr):
if obj.type == 'Gas':
obj.amount = obj.distance * 2
obj.save()
#watch('type', compute_amount, call_on_created=True)
class FuelConsumption(models.Model):
CHOICE = (
('Meal', 'Meal'),
('Gas', 'Gas'),
)
type = models.CharField(max_length=10, choices=CHOICE)
distance = models.CharField(max_length=100)
amount = models.CharField(max_length=100, blank=True, null=True)