django orm, backward relations, - django-models

I have models as,
class Invoice():
class Entry():
invoice = models.ForeignKey(Invoice, on_delete=models.PROTECT, related_name='entries')
amount = CurrencyField()
I have to calculate total amount for a invoice by backward relation

A CurrencyField [GitHub] stores a currency, like 'USD', not an amount of a given currency, so not 5 USD. You need a MoneyField to do this.
The modeling thus should look like:
from django.db import models
from djmoney.models.fields import MoneyField
class Invoice(models.Model):
pass
class Entry(models.Model):
invoice = models.ForeignKey(
Invoice, on_delete=models.PROTECT, related_name='entries'
)
amount = MoneyField(max_digits=14, decimal_places=2, default_currency='USD')
You can sum up the currency of an invoice with:
from django.db.models import Sum
my_invoice.entries.aggregate(total=Sum('amount'))['total']
this will only work if the amounts all have the same currency.

Related

Django auto incrementing field that depends on another field

I have a model named Hobbies that has the hobbies for certain participants (this is a ForeignKey relationship). For each certain participant I wish to have an auto incrementing field named priority that shows which hobby is prioritized. For example: participant 1 has 3 hobbies with priorities going from 1 to 3, participant 2 has 5 hobbies with priorities going from 1 to 5. Is there a way to have an auto incrementing field that depends on the participant, without making another table in my database?
This is the class for Hobbies:
class Hobbies(models.Model):
hobby = models.CharField(max_length=255, verbose_name='Add hobby', help_text=_('Vul hier 1 van je hobbies in.'))
priority = models.IntegerField()
participant = models.ForeignKey(Deelnemer, on_delete=models.CASCADE)
class Meta:
ordering = ['priority']
verbose_name_plural = 'Hobbies'
def __str__(self):
return self.hobby
If you need more information, I'll add it.

Many to Many Relationship in a Transactional System With Google Datastore/Python NDB

I am writting an application for a crop warehousing company, which purchases the harvested crop and stores it in one or more warehouses. Till now limitations of Google App Engine/Datastore was not posing problem to me. And I so deep into the project that it's very difficult to return.
I have to establish a many to many relationship between two Kinds which are transactional (means parent/ancestor queries) in nature. I am not sure what is the right approach to do this. This is the business logic:
Warehouse issues a purchase order for a specific quantity (PO). So we create an entity in PO Kind for each purchase order (PO).
Goods are received at the warehouse. So we create an entity in GRN Kind. (GRN=Goods Receiving Notes).
Here is many to many relationship.
One GRN may be required to complete one PO.
One GRN may be required to complete many POs.
Many GRNs may be required to complete one PO.
Many GRNs may be required to complete many POs.
This is a relevent snapshot of the code.
class Warehouse(ndb.Models):
name = ndb.TextProperty()
capacity = ndb.FloatProperty()
current_stock = ndb.FloatProperty()
class PurchaseOrder(ndb.Models):
quantity = ndb.FloatProperty()
remaining = ndb.FloatProperty()
is_complete = ndb.BooleanProperty()
grn = ndb.KeyProprty(repeated=True, kind=GRN)
class GRN(ndb.Models):
quantity = ndb.FloatProperty()
remaining = ndb.FloatProperty()
is_complete = ndb.BooleanProperty()
po = ndb.KeyProprty(repeated=True, kind=PurchaseOrder)
Entity Group Relationships
Warehouse -> GRN
Warehouse -> PO
To establish many - to - many relationship I hold all the related GRN Keys in a PO record and all related PO Keys in a GRN record. This is working fine for me.
But in case I have to edit a GRN or PO in the back date, then I am not able to handle the complication of cascaded changes which may impact other GRNs and POs.
Somewhere I read I should be using a third model to hold the many - to - many relationship, rather than storing the related keys. I am not able to visualize what that third table to should contain. *
I know my problem is very specific and I have not funished all the details. But just help me with the right approach for this kind of problem pattern. I will handle the rest. Or provide any link if this is already documented somewhere.
I would add a many-to-many relationship called GRNinstance that links a single GRN instance with a single PO:
class PurchaseOrder(ndb.Models):
quantity = ndb.FloatProperty()
remaining = ndb.FloatProperty()
is_complete = ndb.BooleanProperty()
class GRN(ndb.Models):
quantity = ndb.FloatProperty()
remaining = ndb.FloatProperty()
is_complete = ndb.BooleanProperty()
class GRNinstance(ndb.Models):
po = ndb.KeyProperty(kind=PurchaseOrder)
grn = ndb.KeyProperty(kind=GRN)
quantity = ndb.FloatProperty()
The sum of GRNinstance.quantity for a particular po should add up to PurchaseOrder.quantity, and the sum of GRNinstance.quantity for a particular grn should add up to GRN.quantity.
In fact, Dmitry's ComputedProperty could replace both PurchaseOrder.quantity and GRN.quantity (but that could be slow). Maybe is_complete could be a simple test:
is_complete = ndb.ComputedProperty(lambda self: self.remaining > 0)

Database design in website that sells tickets for events with Django

I'm working on a website that sells tickets for events. And I have the following design:
And the (simplified for posting) models:
class Event(models.Model):
name = models.CharField(max_lenght=20)
class Date(models.Model):
event_start = models.DateTimeField()
event = models.ForeignKey(Event)
class Ticket_Class(models.Model):
name = models.CharField(max_lenght=20)
price = models.IntegerField()
event = models.ForeignKey(Event)
How should I add a Ticket model? Because a Ticket is for an Event on a particular Date, so I would need to relate a ticket to the relationship between Event and Date
A Ticket_Class should also have a "max" field where is stored the maximum tickets available to sell for that particular Ticket_Class on a particular Date. E.g.: Event "Metallica" has Ticket_Class "Field" and Ticket_Class "VIP", both on three different dates. How would I access the number of remaining tickets for a Ticket_Class on a particular Date? Maybe counting how many Tickets are in the Ticket table corresponding to that Event on that Date.
I hope I made myself clear, english is not my first language. Feel free to ask any doubts
I think your design should be something like this:
class Event(models.Model):
name = models.CharField(max_lenght=20)
class Date(models.Model):
event_start = models.DateTimeField()
event_end= models.DateTimeField()
class Ticket_Class(models.Model):
name = models.CharField(max_lenght=20)
price = models.IntegerField()
type= models.CharField(max_lenght=20)
class EventTicketSell(models.Model):
event= models.ForeignKey(Event)
date= models.ForeignKey(Date)
ticket= models.ForeignKey(Ticket_Class)
max_sellable_tickets= models.IntegerField()
Reason for this design is that you can add a event to EventTicketSell class, then assign date and ticket with max sellable tickets.
for adding ticket/date/event:
event1= Event(name= "Lion King")
event1.save()
event2= Event(name= "Metallica")
event2.save()
vip_ticket= Ticket_Class(name='VIP', price= 100, type='VIP')
vip_ticket.save()
evening_show= Date(event_start='Date Object', event_end= 'Date Object') # Date Object is like datetime.datetime.now()
evening_show.save()
concert_ticket_sell= EventTicketSell(event=event1, ticket=vip_ticket, date= evening_show, max_sellable_ticket=500)
concert_ticket_sell.save()
movie_ticket_sell= EventTicketSell(event=event2, ticket=vip_ticket, date= evening_show, max_sellable_tickets=500)
movie_ticket_sell.save()
This design will keep objects reusable and flexible to modify. For example, if you want to change max_sellable_ticket then:
movie_ticket_sell= EventTicketSell.objects.filter(event__name='Lion King', date__event_start= datetime.datetime.now(), ticket__type= 'VIP')[0]
movie_ticket_sell.max_sellable_tickets -= form.cleaned_data['ticket_sold'] #for example we get sold count from form
movie_ticket_sell.save()
It seems like the event needs to have a ticket amount field to verify what the max tickets are. Then it should have a foreign key relationship with the ticket_class. In order to make sure you do not exceed the amount of tickets available then you would probably need to use something like the clean method to verify it does not exceed when associating a ticket to an event.
https://docs.djangoproject.com/en/1.5/ref/models/instances/#django.db.models.Model.clean
I'm just looking at this from a high level so maybe I'm missing something. I'm also unclear why you can't just have the date be a field in the event?

GeoDjango distance query weighted by rating

I am using GeoDjango/PostGIS and have a model called Business that has a physical location and a rating. I would like to run a query to find 'nearest' highly rated businesses. How do I do this? To make it more concrete, suppose given a location, I want to find businesses sorted by rating/(1+distance). What is the best way to go about this?
from django.contrib.gis.db import models
class Business(models.Model):
name = models.CharField(max_length=255)
rating = models.IntegerField()
address = models.PointField()
I don't think you can sort by min distance in geodjango, but you can filter by distance, and only get the ones near of your point, and then order by rating.
from django.contrib.gis.geos import *
pnt = Point(954158.1, 4215137.1, srid=32140)
pnt.buffer(23) #radius
business = Business.objects.filter(address__intersects=pnt).order_by('rating')
In postgis you could get what you are asking for with a simple query like this:
SELECT name, rating,
ST_Distance(the_geom,ST_GeomFromEWKT('SRID=4326;POINT(19.232 91.00)') AS minDist
FROM business ORDER BY minDist,rating;

How to perform a many-to-many filter using ReferenceProperty in Google App Engine?

This is my model, Players and Clubs. As a Club can have many players and a player can have many clubs (in its carrer), I used a many-to-many relationship:
class Club(db.Model):
name = db.StringProperty()
link = db.StringProperty()
class Player(db.Model):
name = db.StringProperty()
link = db.LinkProperty()
class ClubHasPlayer(db.Model):
club = db.ReferenceProperty(Club, required=True,
collection_name='club_players')
player = db.ReferenceProperty(Player, required=True,
collection_name='player_clubs')
number = IntegerProperty()
Now, I have a search interface where one can search for all players, and add zero or more restrictions, such as player name, and club where he played. Thus, I have a cascade type of handling this:
players = player.all()
if filter_by_player_name:
players.filter("name =",filter_by_player_name)
Now, I want to do this:
if filter_by_club_name:
players.filter(????)
I still think in terms of SQL, and it should be something like a nested clause :
select * from player where player.name='x' and player.id in (select club_has_player.player_id from club_has_player, club where club_has_player.club_id = club.id and club_name = "Y")
How to do it?
I know I could go from the club, that is:
club = Club.filter("name =",filter_by_club_name).get()
club.club_players
but this style discards a previous filter, that could be player names...
Can anybody help me here? Thanks.
One common advice in the GAE community is to denormalize your models. This can be useful in this specific situation. You can store the club name in every player entity as a string, in addition to the reference property to the club:
class Player(db.Model):
name = db.StringProperty()
link = db.LinkProperty()
club = db.ReferenceProperty(club)
club_name = db.StringProperty()
This would allow you to easily filter Players by club name.
Obviously, this makes changing club names harder. But the probability of having to change a club name is low.

Resources