Python django query database and get all FKs in list - python

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.

Related

How to implement a database for storing parentId and a list of children?

I need to implement a POST request with data loading via two keys: "items" and "UpdateDate".
But in the database with items it is necessary to store the parent (parentId) of the category /product and a list of children (children).
and record the time from the "UpdateDate" key in the date field for all categories/products imported for this request
The screenshots below show a detailed TT.
I haven't been able to figure out how to implement a database on Django/Django Rest Framework for a week.
Screens:
class ShopUnit(models.Model):
id = models.UUIDField(primary_key=True, verbose_name='Unique identifier', default=uuid.uuid4, editable=False,
null=False)
name = models.CharField(max_length=255, verbose_name='Category/Product name', null=False)
date = models.ForeignKey('Date', on_delete=models.CASCADE, related_name='date', null=True, blank=True)
parentId = models.ForeignKey("self", on_delete=models.CASCADE, null=True, blank=True, related_name='сhilden',
db_index=True)
type = models.CharField(max_length=10, verbose_name='Element Type', choices=ShopUnitType.choices)
price = models.PositiveIntegerField(null=True, blank=True, verbose_name='Цена')
children = models.ForeignKey("self", null=True, blank=True, on_delete=models.SET_NULL, related_name='parent')
There are small developments:
https://i.stack.imgur.com/GdAaK.png
https://i.stack.imgur.com/fzBdS.png
https://i.stack.imgur.com/LRQIq.png
https://i.stack.imgur.com/tssis.png

Django multiple foreign key to a same table

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.

Django doesn't see fk in other table

I have some models and fk on them to others.
models.py
class ElementMessages(models.Model)
element = models.ForeignKey(Element, on_delete=models.CASCADE)
sender = models.ForeignKey(UserAccount, on_delete=models.SET_NULL, null=True)
text = models.TextField(max_length=512, null=True)
send_time = models.DateTimeField(auto_now_add=True)
type = models.CharField(max_length=16, choices=MESSAGE_TYPES, default=SIMPLE)
type_dialog = models.CharField(max_length=10, choices=DIALOG_TYPE, default=DIALOG_TALK)
request = models.ForeignKey(ChatRequest, null=True, default=None, on_delete=models.CASCADE)
post_work = models.ForeignKey(PostWork, null=True, default=None, on_delete=models.CASCADE)
files = models.BooleanField(default=False)
class Element(models.Model):
id = models.UUIDField(default=uuid.uuid4, editable=False, unique=True, primary_key=True)
artist = models.ForeignKey(Artist, on_delete=models.CASCADE, related_name='chat_element', null=True, blank=True)
customer = models.ForeignKey(Customer, on_delete=models.CASCADE, related_name='chat_element', null=True, blank=True)
element = models.ForeignKey('projects.Element', null=False, on_delete=models.CASCADE, related_name='chat_element')
When I try to delete Element object, it raises this:
django.db.utils.IntegrityError: insert or update on table "chat_elementmessages" violates foreign key constraint "chat_elementmessages_element_id_672e2ba2_fk_chat_element_id"
DETAIL: Key (element_id)=(87cdd8d7-47f0-4264-8aa7-ae21a8246fd8) is not present in table "chat_element".
But when I look at table in db, this key exists.
How to fix that?
As it turned out, problems were at Django pre_delete andpost_delete signals. They tried to refer to a non-existing object, that I'm try to delete. Fixed with simple check on the existence of the object.

model design for considering multiple work schedule with number

I am trying to create convincing job hiring model. However I got stuck to show the conditions like 3 Full Time, 2 Part Time in a single job. For example, a company may post job for senior backend developer with job description and all where he may select both Full Time and Part Time work schedule. Probably he want to state how many Full Time and Part Time employer for that job. That is why I am using ManyToManyField for work schedule but I am not sure for the numbers of employeer for certain workschedule in an efficient manner.
Here is the model design that I have designed for now
class Category(models.Model):
name = models.CharField(max_length=200, unique=True)
slug = models.SlugField(max_length=50, unique=True)
description = models.CharField(max_length=400, blank=True, null=True)
class WorkSchedule(models.Model):
name = models.CharField(max_length=100, blank=False, null=False)
slug = models.SlugField(max_length=50, unique=True)
class Position(models.Model):
name = models.CharField(max_length=100, blank=False, null=False)
slug = models.SlugField(max_length=50, unique=True)
class Job(models.Model):
company = models.ForeignKey(
Company, related_name='jobs', on_delete=models.CASCADE)
job_title = models.CharField(max_length=200, blank=True, null=True)
category = models.ForeignKey(Category, related_name='jobs')
description = models.TextField(blank=False, null=False)
city = models.CharField(max_length=100, blank=False, null=False)
position = models.ManyToManyField(
Position, related_name='jobs', blank=False, null=False)
work_schedule = models.ManyToManyField(
WorkSchedule, related_name='jobs', blank=False, null=False)

Do not allow same value in different columns for the same record in django

I am building a website in django that will allow players to be matched with other players. I have the following model:
class Session(models.Model):
# id = AutoField(primary_key=True) added automatically.
sport = models.ForeignKey('Sport', unique=False, blank=False, null=False, on_delete=models.CASCADE, )
hostplayer = models.ForeignKey('Member', unique=False, blank=False, null=False, on_delete=models.CASCADE, related_name='member_host', )
guestplayer = models.ForeignKey('Member', unique=False, blank=True, null=True, on_delete=models.CASCADE, related_name='member_guest', )
date = models.DateField(blank=False, null=False, )
time = models.TimeField(blank=False, null=False, )
city = models.ForeignKey('City', unique=False, blank=False, null=False, on_delete=models.CASCADE, )
location = models.CharField(max_length=64, unique=False, blank=False, null=False, )
price = models.FloatField(unique=False, blank=False, null=False, default=0, )
details = models.TextField(unique=False, blank=True, null=False, )
def __unicode__(self):
return unicode(self.id)
As you can see, both hostplayer and guestplayer are foreign keys of the Member table.
The problem is that when I go into django admin, if I select the hostplayer as jack, I can also select the guestplayer as jack. This is obviously wrong as a player cannot play against himself.
How can I limit the options of guestplayer to not include the hostplayer?
Also, on the models level, is there a way to specify that the value of one attribute must be different from the value of another attribute in the same tuple? An obvious way would be to use forms and validate them but I am curious whether a simpler alternative exists.

Categories

Resources