So, i have two models: RetailStore and Product. Product contains a ForeignKey to RetailStore and a field named sku. Basically what i need is to make sure that the sku field is unique into a store, but not between all stores, e.g:
Store1: Product(sku="sku1"), Product(sku="sku2"), Product(sku="sku3"), Product(sku="sku1") <- can't have this last one because it already exists.
Store2: Product(sku="sku1"), Product(sku="sku2"), Product(sku="sku3") <- This is ok
Store3: [...] <- Same goes for others Store.
My Models
class RetailStore(StandardModelMixin):
cnpj = models.CharField(
blank=False, null=False, unique=True, max_length=200, validators=[validate_cnpj], verbose_name="CNPJ"
)
[other fields...]
class Product(StandardModelMixin, SoftDeletionModel):
sku = models.CharField(blank=False, null=False, max_length=200, verbose_name="SKU")
[other fields...]
retail_store = models.ForeignKey(
RetailStore,
on_delete=models.CASCADE,
blank=True,
null=True,
related_name="products",
verbose_name="Retail Store",
)
You can use UniqueConstraint so you can have the same SKUs in different stores, but not in one.
class Product(StandardModelMixin, SoftDeletionModel):
...
class Meta:
constraints = [models.UniqueConstraint(
fields=['sku', 'retail_store'],
name='unique_sku_in_store'
)]
You'll need to apply validate_unique to this.
Django offers unique_together, but it grants uniqueness to a single model and not between models.
Docs: https://docs.djangoproject.com/en/dev/ref/models/instances/#django.db.models.Model.validate_unique
Related
I have 2 models, and I wanted to search with a Many to Many field according to my structuring, below is my models :
class User(django_models.AbstractBaseUser, TimeStampedModel,
django_models.PermissionsMixin):
"""
User model for the user creation
"""
uuid = models.UUIDField(unique=True, max_length=500,
default=uuid.uuid4,
editable=False,
db_index=True, blank=False, null=False)
account_types = models.ManyToManyField(AccountTypes,
related_name='account_types')
Then another model AccountTypes :
class AccountTypes(TimeStampedModel, models.Model):
"""
Account types for the users. e.g Mentors, Mentees, Parents etc.
"""
uuid = models.UUIDField(unique=True, max_length=500,
default=uuid.uuid4,
editable=False,
db_index=True, blank=False, null=False)
name = models.CharField(_('Account Name'), max_length=30, blank=False,
null=False)
How can I search a user uuid with the certain AccountType ?
My try was like this :
User.objects.get(uuid=uuid, account_types__in=['Mentor'])
But I got this error :
ValueError: Field 'id' expected a number but got 'Mentor'.
You should filter on the name of the account_types, so:
User.objects.get(uuid=uuid, account_types__name='Mentor')
or if you want all User objects that are a mentor, you can work with:
User.objects.filter(account_types__name='Mentor')
I have an order model with a one to many relation to a OrderDate Model. Now I want have an additional field on order named 'chosen_date' with a one to one relation to the same OrderDate Model. The Problem is that my relations at OrderDate both have the name 'order', which clashes. How can I solve this problem without adding a new field like 'Order_2' on the OrderDate Model?
Here are my models:
class Order(TimeStampedModel):
chosen_date = models.OneToOneField('OrderDate', on_delete=models.CASCADE, blank=True, null=True)
class OrderDate(TimeStampedModel):
order = models.ForeignKey(Order, related_name='dates', on_delete=models.CASCADE)
date = models.DateField()
morning = models.BooleanField(default=False)
noon = models.BooleanField(default=False)
evening = models.BooleanField(default=False)
You specify the related_name for the OneToOneField:
class Order(TimeStampedModel):
chosen_date = models.OneToOneField(
'OrderDate',
related_name='order_picked',
on_delete=models.CASCADE,
blank=True,
null=True
)
I have a model:
class Industry(models.Model):
name = models.CharField(max_length=60, unique=True, null=False, blank=False)
I want it to have a sub_industries field that will hold all of its sub industries, which should be instances of Industry model.
I cannot be ManyToMany because each industry has only one parent industry.
You can add a ForeignKey to itself with:
class Industry(models.Model):
name = models.CharField(max_length=60, unique=True)
parent_industry = models.ForeignKey(
'self',
null=True,
related_name='sub_industries'
)
You can use NULL/None to express that an industry has no parent.
I have the following model in Django
class Transfer(models.Model):
user = models.ForeignKey(User, on_delete=models.PROTECT, limit_choices_to={'is_accepted':True})
amount = models.IntegerField(default=0)
transfer_date = models.DateTimeField(default=timezone.now)
company = models.ForeignKey(Company, on_delete=models.PROTECT)
I would like to filter the users based on is_accepted field. The problem is, that this field is declared in a model called Employee, which is in onetoone relationship with user.
Is there any possibility to reach Employee fields and filter them in this manner?
You can normally define a filter like:
class Transfer(models.Model):
user = models.ForeignKey(
User,
on_delete=models.PROTECT,
limit_choices_to={'employee__is_accepted': True}
)
amount = models.IntegerField(default=0)
transfer_date = models.DateTimeField(default=timezone.now)
company = models.ForeignKey(Company, on_delete=models.PROTECT)
I would like to reference 2 separate fields from a model into another model.
From the code below, i have:
First model with the following fields - name, owner and email
In the second model, i would like to use the data from name and owner above in the second model but renamed them org (name form group) and org_owner (owner from group)
i have tried the below code using related_name. But i get thesame value in both fields. That is a get the name field from group in both the org and org_owner field. Not what i want.
class group(models.Model):
name = models.CharField(max_length=100, unique=True, blank=False)
owner = models.CharField(max_length=100, blank=False)
email = models.EmailField(max_length=100, blank=False)
class account(models.Model):
org = models.ForeignKey('group', on_delete=models.SET_NULL, null=True, related_name='org')
org_owner = models.ForeignKey('group', on_delete=models.SET_NULL, null=True, related_name='org_owner')
account = models.CharField(max_length=100, blank=False, unique=True)
Expected result should be:
account.org = group.name
account.org_owner = group.owner
There is no need to have group owner in the account once you have added the org as a foreign key.
You should remove the line below from account:
org_owner = models.ForeignKey('group', on_delete=models.SET_NULL, null=True, related_name='org_owner')
Group name can be accessed as:
account.org.owner
And group name should be accessible as
account.org.name
Seems like what you're trying to do is join account with group using a condition on two fields. I would suggest you search for how to use a foreign key of two fields rather than using two foreign keys. The other popular way of solving this is to give the group model a generated primary key and have a group_id in the account for the relation. You could then remove (org, org_owner) from account if it serves no other purpose.