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')
Related
I have a model of product and another model called Course that inherits the product but has a video field and an author Which is a ForeignKey with A teacher model which inherits from the user model which inherits from AbstractUser
Related Models:
class User(AbstractUser):
username = models.SlugField(default="", null=False, db_index=True, blank=True) # forced by django admin problems :(
password = models.CharField(max_length=255, null=True)
email = models.EmailField(max_length=255, unique=True)
group = models.ManyToManyField(Group)
is_teacher = models.BooleanField(default=False, null=False)
is_seller = models.BooleanField(default=False, null=False)
phoneNum = PhoneNumberField(null=False, unique=True, default='')
USERNAME_FIELD = "email"
REQUIRED_FIELDS = ["username", "first_name", "last_name", "password"]
def save(self, *args, **kwargs):
self.username = slugify(self.first_name + self.last_name)
super().save(*args, **kwargs)
class Product(models.Model):
name = models.CharField(max_length=100, null=False, blank=True)
shoppers = models.ManyToManyField(User, related_name='shopper')
tumb = models.ImageField(upload_to=course_tumb_directory_path, null=False)
lastUpdate = models.DateTimeField(auto_now=True)
price = models.DecimalField(null=False, default=1000000, max_digits=7, decimal_places=0)
class Teacher(User):
TOPICS = [
("BP", "Basic Programming"),
("AP", "Advanced Programming"),
("CS", "Computer Science"),
("MS", "Mathematics"),
("CH", "Chemistry"),
("BL", "BioLogy"),
("PH", "physics"),
("EL", "Electronics"),
("RG", "Religious"),
("Or", "Other"),
]
topic = models.CharField(max_length=2, choices=TOPICS, default=TOPICS[-1][0])
class Course(Product):
video = models.FileField(upload_to=course_directory_path, null=True,
validators=[
FileExtensionValidator(allowed_extensions=['MOV', 'avi', 'mp4', 'webm', 'mkv'])])
author = models.ForeignKey(Teacher, on_delete=models.CASCADE, null=True)
when I'm trying to make migrations it says this:
It is impossible to add a non-nullable field 'product_ptr' to course without specifying a default. This is because the database needs something to populate existing rows.
I'm using PostgreSQL for my db, It didn't let me flush it so I Dropped it and ReCreated a new one
But I Still can't makemigrations
I tried these answers:
You are trying to add a non-nullable field 'new_field' to userprofile without a default
Django: You are trying to add a non-nullable field 'slug' to post without a default; we can't do that
It is impossible to add a non-nullable field 'id' to video without specifying a default
You are trying to add a non-nullable field 'id' to contact_info without a default
Error : "You are trying to add a non-nullable field"
I faced these kinds of errors before but one thing I couldn't figure out is that it isn't related to a field so I can't fix it
Python: 3.10.6
Django: 4.1
PostgreSQL: psql 14.6
OS: Ubuntu 22.04 (Not a VM)
I figured out that so many repetitive inheritances made this error not sure why but this solves it:
class BaseProduct(models.Model):
class Meta:
abstract = True
name = models.CharField(max_length=100, null=False, blank=True)
shoppers = models.ManyToManyField(User)
tumb = models.ImageField(upload_to=course_tumb_directory_path, null=False, blank=True)
lastUpdate = models.DateTimeField(auto_now=True)
price = models.DecimalField(null=False, default=1000000, max_digits=7, decimal_places=0)
class Product(BaseProduct):
count = models.DecimalField(null=False, default=1, max_digits=7, decimal_places=0)
class Course(BaseProduct):
video = models.FileField(upload_to=course_directory_path, null=True,
validators=[
FileExtensionValidator(allowed_extensions=['MOV', 'avi', 'mp4', 'webm', 'mkv'])])
author = models.ForeignKey(Teacher, on_delete=models.CASCADE, null=True, related_name='courses')
Inheriting from an abstract model instead of repetitive Inheritance
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
I am new in django and I am working in order to implement a Rest API. My issue is with a query that I can't find a working solution no matter the number of hours spent on it. More specifically I have these two models:
class Subcategory(models.Model):
id = models.UUIDField(primary_key=True, editable=False, null=False, blank=False, default=uuid.uuid4)
name = models.CharField(max_length=50, null=False, blank=False)
category = models.ForeignKey(Category, on_delete=models.CASCADE, null=False, blank=False, db_column='category')
class Category(models.Model):
id = models.UUIDField(primary_key=True, editable=False, null=False, blank=False, default=uuid.uuid4)
name = models.CharField(max_length=50, null=False)
image = models.CharField(max_length=100, default=None)
As you can see each category has one or more subcategories and in the subcategory model I have a foreign key to the category. What i want to do is to query my database, get all categories and to each category add an extra field subcategories with a list of the subcategories. My idea it was to follow the FKs using .select_related but it seems to be a wrong solution since I am taking the following error:
"message": "name 'subcategory__category' is not defined"
My query is:
Category.objects.all().select_related(subcategory__category).values()
Any ideas on how to solve this issue and find a way to implement my query?
Thank you in advance
Do it like this
class Category(models.Model):
id = models.UUIDField(primary_key=True, editable=False, null=False, blank=False, default=uuid.uuid4)
name = models.CharField(max_length=50, null=False)
image = models.CharField(max_length=100, default=None)
sub_cat = ManyToManyField(Subcategory, blank=True)
class Subcategory(models.Model):
id = models.UUIDField(primary_key=True, editable=False, null=False, blank=False, default=uuid.uuid4)
name = models.CharField(max_length=50, null=False, blank=False)
def __str__(self):
return self.name
Now,query part
temp = []
all_cat = Category.objects.all()
for cat in all_cat:
temp.append( list(cat.sub_cat.all()) )
I think this is what you want to do.
I need to log the transaction of the item movement in a warehouse. I've 3 tables as shown in the below image. However Django response error:
ERRORS:
chemstore.ItemTransaction: (models.E007) Field 'outbin' has column name 'bin_code_id' that is used by another field.
which is complaining of multiple uses of the same foreign key. Is my table design problem? or is it not allowed under Django? How can I achieve this under Django? thankyou
DB design
[Models]
class BinLocation(models.Model):
bin_code = models.CharField(max_length=10, unique=True)
desc = models.CharField(max_length=50)
def __str__(self):
return f"{self.bin_code}"
class Meta:
indexes = [models.Index(fields=['bin_code'])]
class ItemMaster(models.Model):
item_code = models.CharField(max_length=20, unique=True)
desc = models.CharField(max_length=50)
long_desc = models.CharField(max_length=150, blank=True)
helper_qty = models.DecimalField(max_digits=10, decimal_places=4)
unit = models.CharField(max_length=10, blank=False)
def __str__(self):
return f"{self.item_code}"
class Meta:
verbose_name = "Item"
verbose_name_plural = "Items"
indexes = [models.Index(fields=['item_code'])]
class ItemTransaction(models.Model):
trace_code = models.CharField(max_length=20, unique=False)
item_code = models.ForeignKey(
ItemMaster, related_name='trans', on_delete=models.CASCADE, null=False)
datetime = models.DateTimeField(auto_now=False, auto_now_add=False)
qty = models.DecimalField(max_digits=10, decimal_places=4)
unit = models.CharField(max_length=10, blank=False)
action = models.CharField(
max_length=1, choices=ACTION, blank=False, null=False)
in_bin = models.ForeignKey(
BinLocation, related_name='in_logs', db_column='bin_code_id', on_delete=models.CASCADE, null=False)
out_bin = models.ForeignKey(
BinLocation, related_name='out_logs', db_column='bin_code_id', on_delete=models.CASCADE, null=False)
remarks = models.TextField(blank=True)
def __str__(self):
return f"{self.trace_code} {self.datetime} {self.item_code} {dict(ACTION)[self.action]} {self.qty} {self.unit} {self.in_bin} {self.out_bin}"
you have same db_column in two fields so change it
in_bin = models.ForeignKey(
BinLocation, related_name='in_logs', db_column='bin_code_id', on_delete=models.CASCADE, null=False)
out_bin = models.ForeignKey(
BinLocation, related_name='out_logs', db_column='other_bin_code', on_delete=models.CASCADE, null=False) /*change db_column whatever you want but it should be unique*/
If are linked to the same model name, You should use different related_name for each foreign_key filed . here is the exemple :
address1 = models.ForeignKey(Address, verbose_name=_("Address1"),related_name="Address1", null=True, blank=True,on_delete=models.SET_NULL)
address2 = models.ForeignKey(Address, verbose_name=_("Address2"),related_name="Address2", null=True, blank=True,on_delete=models.SET_NULL)
thank you for everyone helped. According to Aleksei and Tabaane, it is my DB design issue (broken the RDBMS rule) rather than Django issue. I searched online and find something similar: ONE-TO-MANY DB design pattern
In my case, I should store in bin and out bin as separated transaction instead of both in and out in a single transaction. This is my solution. thankyou.
p.s. alternative solution: I keep in bin and out bin as single transaction, but I don't use foreign key for bins, query both in bin and out bin for the bin selection by client application.
Please help to understand how to correct limit for "team" field by "company" team?
It's my code :
class CustomCompany(models.Model):
company_name = models.CharField(max_length=30,
default="None",
unique=True
)
class CustomTeam(models.Model):
team_name = models.CharField(
max_length=30,
default="None"
)
company_name = models.ForeignKey(CustomCompany,
on_delete=models.CASCADE,
related_name='company_name+',
to_field='id',
)
class CustomUser(AbstractUser):
phone = models.CharField(max_length=20, blank=True)
company = models.ForeignKey(CustomCompany,
on_delete=models.CASCADE,
default='None',
to_field='company_name',
related_name='company'
)
team = models.ForeignKey(CustomTeam,
on_delete=models.CASCADE,
default=1,
related_name='team_name+',
limit_choices_to={"company_name_id":"company_id"},
)
And problem in last string (limit_choices_to)
How to correct do this, limit teams by company?
Current error, if it's required the next :
invalid literal for int() with base 10: 'company_id'
Considering that CustomTeam already belongs to a CustomCompany, have you considered dropping the field CustomUser.company and just using CustomUser.team.company ?
The models stay almost the same:
class CustomCompany(models.Model):
...
class CustomTeam(models.Model):
...
company = models.ForeignKey(CustomCompany, ...)
class CustomUser(AbstractUser):
...
team = models.ForeignKey(CustomTeam, ...)
A few notes:
a ForeingKey should not have a int as default value, it has to be a model instance; I would just leave the default out of the model definition.