django EAV filtering - django

I have the following models.
class Category(MPTTModel):
name = models.CharField(max_length=100, null=False, blank=False)
parent = TreeForeignKey('self', null=True, blank=True, related_name='children')
def __unicode__(self):
return self.name
class Product(models.Model):
name = models.CharField(max_length=250, null=False, blank=False)
category = models.ForeignKey('Category')
price = models.DecimalField(decimal_places=2, max_digits=7)
def __unicode__(self):
return self.name
class ProductAttribute(models.Model):
products = models.ManyToManyField('Product')
category = models.ForeignKey('Category')
property = models.CharField(max_length=250, null=False, blank=False)
value = models.CharField(max_length=250, null=False, blank=False)
I need to be able to select products based on a given category, and a given attribute.
For example, if I have the product "Blender", I want to select all blenders within a given category, with a given attribute (such as brand = black & decker).

Related

Timestamped model __init__() got multiple values for argument 'on_delete'

I'm trying to create a foreignkey relationship in DRF models with an on_delete
fk_city = models.ForeignKey("region_mgmt.City", "warehouses", on_delete=models.SET_NULL)
TypeError: __init__() got multiple values for argument 'on_delete'
below is my code:
from django_extensions.db.models import TimeStampedModel
class State(TimeStampedModel, models.Model):
id = models.UUIDField(default=uuid.uuid4, primary_key=True)
name = models.CharField(max_length=100)
postal_code = models.CharField(max_length=20, blank=True, null=True)
fk_country = models.ForeignKey(Country, related_name="states", on_delete=models.CASCADE)
def __str__(self):
return self.name
class City(TimeStampedModel, models.Model):
id = models.UUIDField(default=uuid.uuid4, primary_key=True)
name = models.CharField(max_length=100)
postal_code = models.CharField(max_length=20, blank=True, null=True)
fk_state = models.ForeignKey(State, related_name="cities", on_delete=models.CASCADE)
def __str__(self):
return self.name
and in another module I have the following model
class Warehouse(TimeStampedModel, models.Model):
id = models.UUIDField(default=uuid.uuid4, primary_key=True)
name = models.CharField(max_length=255, null=False, blank=False)
address = models.TextField(null=False, blank=False)
fk_city = models.ForeignKey("region_mgmt.City", "warehouses", on_delete=models.SET_NULL)
contact_no = models.CharField(max_length=100)
does anyone know the reason and its solution?
The second parameter of a ForeignKey is the on_delete=… parameter [Django-doc], so you specify two values for this. Likely you want to use your warehouses as related_name=… parameter [Django-doc], so you implement this as:
class Warehouse(TimeStampedModel, models.Model):
# …
fk_city = models.ForeignKey(
'region_mgmt.City',
related_name='warehouses',
on_delete=models.SET_NULL,
null=True
)

Django left join (only two models)

I'm stack on it, please need your help.
I have two models and a want to select all (or filtered) fields from Channel and left join last_published video from Video model. Need good solution using django ORM.
class Channel(models.Model):
name = models.CharField(max_length=150, blank=False, null=False)
url = models.CharField(max_length=100, blank=False, null=False)
def __str__(self):
return self.name
class Video(models.Model):
channel = models.ForeignKey(Channel, on_delete=models.CASCADE)
title = models.CharField(max_length=150, blank=False, null=False)
url = models.CharField(max_length=50, blank=False, null=False, unique=True)
publish_date = models.DateTimeField(blank=True, null=True, auto_created=False)
embedurl = models.CharField(max_length=50, blank=True, null=True, unique=True)
def __str__(self):
return self.title

Django create nested model

I want to create a Model in which I can store the same models as for example in a folder there can be several folders.
I tried like this:
class Service(models.Model):
name = models.TextField(default="")
price = models.IntegerField(blank=True, null=True)
def __str__(self):
return self.name
class ServiceType(models.Model):
services_types = models.ManyToManyField(ServiceType, null=True, blank=True)
services = models.ManyToManyField(Service, null=True, blank=True)
name = models.TextField(default="")
But it didn't work. How can this problem be solved?
If you want to reference same model then you have to use quotation 'ModelName' like this.
So your code will be like:
class Service(models.Model):
name = models.TextField(default="")
price = models.IntegerField(blank=True, null=True)
def __str__(self):
return self.name
class ServiceType(models.Model):
services_types = models.ManyToManyField('ServiceType', null=True, blank=True)
services = models.ManyToManyField(Service, null=True, blank=True)
name = models.TextField(default="")

How to get data from two table through one query Django

** I just need one more table join in my query **
I want to get sales of logged-in users with order detail and shipping address.
I am getting sales of current user through this query but i also want get shipping address.
orderitems = OrderItem.objects.filter(
product__user=request.user, order__complete=1).order_by('-date_orderd')
Now i want to get also address, city and state from the Shippingaddress model.
I attached the models below.
this is my current result.
My models:
Order Model:
class Order(models.Model):
user = models.ForeignKey(
User, on_delete=models.CASCADE, blank=True, null=True)
date_orderd = models.DateTimeField(auto_now_add=True)
complete = models.BooleanField(default=False, null=True, blank=False)
transaction_id = models.CharField(max_length=200, null=True)
# product = models.ManyToManyField(OrderItem)
def __str__(self):
return str(self.id)
Order items Model:
class OrderItem(models.Model):
product = models.ForeignKey(
Product, on_delete=models.CASCADE, blank=True, null=True)
order = models.ForeignKey(
Order, on_delete=models.SET_NULL, blank=True, null=True)
quantity = models.IntegerField(default=0, null=True, blank=True)
date_orderd = models.DateTimeField(auto_now_add=True)
user = models.ForeignKey(
User, on_delete=models.SET_NULL, blank=True, null=True)
price = models.FloatField(blank=True, null=True)
def __str__(self):
return str(self.product)
Shipping Address Model:
class ShippingAddress(models.Model):
user = models.ForeignKey(
User, on_delete=models.CASCADE, blank=True, null=True)
order = models.ForeignKey(
Order, on_delete=models.CASCADE, blank=True, null=True)
name = models.CharField(max_length=150)
address = models.CharField(max_length=150)
city = models.CharField(max_length=150)
state = models.CharField(max_length=150)
zipcode = models.CharField(max_length=150)
date_orderd = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.address
What you are looking for is "Select from multiple tables in one query with Django". You can take a look at the answers here.
Why not add another query like the one below
shp_address = ShippingAddress.objects.filter(product__user=request.user)
and if needed send to the client side as part of context, see below
context = {
'orderitems': orderitems,
'shp_address': shp_address
}

How to clone a model instance without cloning database relationship?

I'm building a cart model with the following code.
from django.db import models
class Item(models.Model):
name = models.CharField(max_length=200)
price = models.DecimalField(max_digits=8, decimal_places=2)
def __str__(self):
return self.name
class Order(models.Model):
date = models.DateTimeField(auto_now_add=True)
transcation_id = models.CharField(max_length=200, null=True)
def __str__(self):
return str(self.date)
class OrderItem(models.Model):
item = models.ForeignKey(Item, on_delete=models.CASCADE, blank=True, null=True)
order = models.ForeignKey(Order, on_delete=models.CASCADE, blank=True, null=True)
quantity = models.IntegerField(default=0, blank=True, null=True)
The many-to-one relationship between Item and Order allows one Order to contain many Item and that looks fine.
A model instance can be simply cloned as already answer in this question.
My problem is, if the price of an Item is changed. The price of contained items in Order is change too. But I don't want it to be changed. In the situation that customer already make a purchase, the price cannot be change. Is there anyway to clone the Order instance that completely not related to the other model?
Save the price manually
class OrderItem(models.Model):
item = models.ForeignKey(Item, on_delete=models.CASCADE, blank=True, null=True)
order = models.ForeignKey(Order, on_delete=models.CASCADE, blank=True, null=True)
quantity = models.IntegerField(default=0, blank=True, null=True)
price = price = models.DecimalField(max_digits=8, decimal_places=2, null=True, default=None)
def save():
if self.pk == None:
self.price = self.item.price
super(OrderItem, self).save()