Looks good except that you don’t need profile
field on Transaction
because it’s already on product
/Holding
item. As well as not clear why need to have ManyToMany
on Profile
with product.
So I would refactor that as follows (see comments inline):
class Product(models.Model):
# no need to say 'product_name' because it is on model Product
name = models.CharField(max_length=255, blank=False, unique=True)
slug = models.CharField(max_length=50, blank=True,null=True)
symbol = models.CharField(max_length=50, blank=True,null=True)
# Float does not suite price due to its low precision. Use Decimal instrad
price = models.DecimalField(max_digits=10, decimal_places=2, blank=True, null=True)
capture_date = models.DateField(blank=True,null=True)
logo_address = models.URLField(max_length=255, blank=True)
def __str__(self):
return self.name
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
bio = models.TextField(max_length=500, blank=True)
location = models.CharField(max_length=30, blank=True)
birth_date = models.DateField(null=True, blank=True)
# no need of products here - can be find via Holding
# products = models.ManyToManyField(Product, blank=True, through='Holding')
website = models.URLField(max_length=50, blank=True)
twitter = models.CharField(max_length=50, blank=True)
meta = models.CharField(max_length=50, blank=True)
github = models.CharField(max_length=50, blank=True)
def __str__(self):
return str(self.user)
class Holding(models.Model):
# the field is not product_name - it is actually `product` itself
product = models.ForeignKey(Product, on_delete=models.CASCADE)
profile = models.ForeignKey(Profile, on_delete=models.CASCADE)
product_holding = models.FloatField(max_length=50, blank=True, null=True)
def __str__(self):
return str(self.product_name)
class Transaction(models.Model):
product = models.ForeignKey(Holding, on_delete=models.CASCADE)
amount = models.DecimalField(max_digits=10, decimal_places=2, blank=True, null=True)
price = models.FloatField(max_length=50, blank=True, null=True)
transaction_date = models.DateField(null=True, blank=True)
profile = models.ForeignKey(Profile, on_delete=models.CASCADE)
And filtering:
profile = Profile.objects.get(user = request.user)
transactions = Transaction.objects.filter(
holding__in=Holding.objects.filter(profile=profile)
)
for t in transactions:
product_name = t.holding.product.product_name
price = t.price
product_holding = t.holding.product_holding
If you want to know the products of a specific user (since we removed ManyToMany
):
products = [x.product for x in Holding.objects.filter(profile=profile)]
Or if a specific user hold specific product:
product = Product.objects.get(name='specific_product')
exists = Holding.objects.filter(profile=profile, product=product).exists()
CLICK HERE to find out more related problems solutions.