django select related with 3 tables - python

i have 3 models in django like this:
class SlackConfigurationMode(models.Model):
MODES = (
("NORMAL", "normal"),
("ALERT", "alert"),
("DANGER", "danger")
)
mode = models.CharField(choices=MODES, default=MODES[0][0], max_length=20)
time_send_slack_notification_minute = models.IntegerField(default=0)
time_send_slack_notification_hour = models.IntegerField(default=0)
description = models.TextField(blank=True)
class WebHookConfiguration(models.Model):
webhook_url = models.CharField(max_length=100)
slack_configuration_mode = models.ForeignKey(
SlackConfigurationMode,
on_delete=models.CASCADE,
related_name='webhook_configurations'
)
class MonitorSource(models.Model):
TYPES = (
("FACEBOOK", "facebook"),
("WEBSITE", "website"),
("YOUTUBE", "youtube")
)
target = models.CharField(max_length=100)
type = models.CharField(choices=TYPES, max_length=20)
created_at = models.DateTimeField(auto_now_add=True)
owner = models.ForeignKey("auth.User", on_delete=models.CASCADE)
name = models.CharField(max_length=100)
slack_configuration = models.ForeignKey(
SlackConfigurationMode, on_delete=models.DO_NOTHING,
default=SlackConfigurationMode.objects.filter(mode="NORMAL")[0].id,
related_name='monitor_sources'
)
i want to get data of webhook_configuration and monitorsource filter by slackconfiguration by mode
i use this query:
queryset = SlackConfigurationMode.objects.select_related('webhook_configurations', 'monitor_sources').filter(
mode='HIGH'
)
but have the error:
Invalid field name(s) given in select_related: 'monitor_sources', 'webhook_configurations'. Choices are: (none)
how can i fix it, and why my query won't work, tks

Here, webhook_configurations and monitor_sources are reverese relations and hence you must use prefetch_related(...)
queryset = SlackConfigurationMode.objects \
.prefetch_related('webhook_configurations', 'monitor_sources') \
.filter(mode='HIGH')

Related

problem with django multitable inheritance and django-parler

i have these models:
class Product(TranslatableModel):
productId = models.UUIDField(default=uuid4, primary_key=True, editable=False)
translations = TranslatedFields(
title = models.CharField(max_length=100),
description = models.TextField(max_length = 2000)
)
picture = models.ImageField()
price = models.FloatField()
art_type = models.ForeignKey(ArtType, on_delete=models.SET_NULL, null = True,blank = True)
createdAt = models.DateTimeField(auto_now_add=True)
updatedAt = models.DateTimeField(auto_now=True)
purchase_num = models.PositiveBigIntegerField()
objects = InheritanceManager()
class Course(Product):
languages = models.ManyToManyField(Language)
isChaptersOpen = models.BooleanField(default=True)
but whenever i try to add a new course i get this error message in the django admin panel:
ImproperlyConfigured at /en/admin/products/product/
InheritanceQuerySet class does not inherit from TranslatableQuerySet
why this is happening

Django ORM multiple inner join in query

I want to be able to do queries involving multiple inner joins using Django ORM, here's my model (showing only relevant fields)
class Students(models.Model):
class Status(models.IntegerChoices):
preRegistered = 0 #No ha aceptado terminos y condiciones
Enabled = 1
Disabled = 2
Suspended = 3
Test = 4
id = models.AutoField(primary_key=True)
user = models.ForeignKey(Users, on_delete=models.CASCADE)
trainingPath = models.ForeignKey(trainingPaths, on_delete=models.CASCADE)
status = models.IntegerField(choices=Status.choices, default=0)
creationDate = models.DateTimeField(auto_now_add=True)
modificationDate = models.DateTimeField(auto_now=True)
class Meta():
db_table = 'Students'
class trainingPaths(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=70, blank=False, null=False)
shortName = models.CharField(max_length=10, blank=True)
creationDate = models.DateTimeField(auto_now_add=True)
modificationDate = models.DateTimeField(auto_now=True)
class Meta():
db_table = 'Training_Path'
class Courses(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=70, blank=False, null=False)
path = models.URLField(max_length=500, blank=True, null=True)
shortName = models.CharField(max_length=6, blank=True)
creationDate = models.DateTimeField(auto_now_add=True)
modificationDate = models.DateTimeField(auto_now=True)
course_image = models.URLField(max_length=200, blank=True)
class Meta():
db_table = 'Courses'
class CoursesXTrainingP(models.Model):
id = models.AutoField(primary_key=True)
trainingPath = models.ForeignKey(trainingPaths, on_delete=models.CASCADE)
course = models.ForeignKey(Courses, on_delete=models.CASCADE)
alternativeName = models.CharField(max_length=70, blank=True)
order = models.PositiveIntegerField(blank=False)
creationDate = models.DateTimeField(auto_now_add=True)
modificationDate = models.DateTimeField(auto_now=True)
class Meta():
db_table = 'Courses_X_Training_Paths'
I want to get the information of the courses that a student has according to the value of the "trainingPath".
this is my SQL query
select
courses.id, courses.`name`, courses.course_image
from
students
join
courses_x_training_paths
on
students.trainingPath_id = courses_x_training_paths.trainingPath_id
join
courses
on
courses_x_training_paths.course_id = courses.id
where
students.trainingPath_id=1;
I have tried several ways and none of them have worked, could you please help me?
You can filter with:
Courses.objects.filter(
coursesxtrainingp__trainingPath_id=1
)
The join on the Students model is not necessary, since we already know that the trainingPath_id is one by filtering on the CoursesXTrainingP model.
Note: normally a Django model is given a singular name, so Student instead of Students.
Note: normally the name of the fields in a Django model are written in snake_case, not PascalCase, so it should be: modification_date instead of modificationDate.

Django Rest Framework Integrity Error at NOT NULL constraint fail

i'm trying to post a transaction via django rest framework, however it shows error in django log as below:
IntegrityError at /api/item_trans/
NOT NULL constraint failed: chemstore_itemtransaction.bin_code_id
it has no problem if I post the same data from the Django admin web.
therefore I suppose the problem has happened at DRF
any help is welcome, thank you
models.py
class BinLocation(models.Model):
bin_code = models.CharField(max_length=10, unique=True)
desc = models.CharField(max_length=50)
def __str__(self):
return 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 self.item_code
class Meta:
verbose_name = "Item"
verbose_name_plural = "Items"
indexes = [models.Index(fields=['item_code'])]
class ItemTransaction(models.Model):
# trace_code YYMMDDXXXX where XXXX is random generated
trace_code = models.CharField(max_length=20, unique=False)
item_code = models.ForeignKey(
ItemMaster, on_delete=models.CASCADE, related_name='+', blank=False, 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)
bin_code = models.ForeignKey(
BinLocation, related_name='+', on_delete=models.CASCADE, blank=False, 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.bin_code}"
serializers.py
class ItemMasterSerializer(serializers.ModelSerializer):
class Meta:
model = ItemMaster
fields = '__all__'
class ItemTransactionSerializer(serializers.ModelSerializer):
item_code = serializers.SlugRelatedField(
slug_field='item_code',
read_only=True
)
bin_code = serializers.SlugRelatedField(
slug_field='bin_code',
read_only=True,
allow_null=False
)
class Meta:
model = ItemTransaction
fields = '__all__'
You might need to use 2 fields, one for reading data and the other for creating and updating your data with its source to the main. In your case you could try this:
class ItemTransactionSerializer(serializers.ModelSerializer):
item_code_id = ItemMasterSerializer(read_only=True)
item_code = serializers.PrimaryKeyRelatedField(
queryset=ItemMaster.objects.all(),
write_only=True,
source='item_code_id'
)
bin_code_id = BinLocationSerializer(read_only=True
bin_code = serializers.PrimaryKeyRelatedField(
queryset= BinLocation.objects.all(),
write_only=True,
source='bin_code_id'
)
Since you have null=False in both of your ForeignKeys, DRF expects the corresponding ID. You seem to be getting the error NOT NULL constraint because you are not passing the ID in DRF. So you need to fix that for both bin_code_id and the item_code_id.

Django admin change many to many label text

I have the field as part of a Room class
roomextra = models.ManyToManyField(
to='hotel.RoomExtra',
related_name='room_extra',
verbose_name='room extra',
)
whereby Django has created the many to many relationship for me. This relationship is displayed as a TabularInline:
admin.py
class RoomExtraInLine(admin.TabularInline):
model = Room.roomextra.through
extra = 1
verbose_name = _('Customise Room Extra')
verbose_name_plural = _('Customise Room Extra(s)')
form = AddRoomAddRoomExtrasForm
In the Django admin, if I add a room extra I get the text in the image below:
Room_roomextra object (5)
above the option I have selected. How can I change the Room_roomextra string?
Update
Code as requested
class RoomExtra(models.Model):
PER_PERSON = 0
PER_ROOM = 1
PER_CHOICES = [
(PER_PERSON, _('Person')),
(PER_ROOM, _('Room')),
]
name = models.CharField(max_length=100)
cost = models.DecimalField(
default="0.00",
max_digits=10,
decimal_places=2,
validators=[MinValueValidator(Decimal('0.00'))],
)
cost_per = models.IntegerField(
choices=PER_CHOICES,
default=PER_ROOM,
verbose_name=_('Cost per'),
)
def __str__(self):
return self.name
class Room(models.Model):
name = models.CharField(max_length=100)
type = models.ForeignKey(
to='hotel.RoomType',
on_delete=models.CASCADE,
)
location = models.ForeignKey(
to='hotel.Location',
on_delete=models.CASCADE,
)
description = models.TextField(
blank=True,
max_length=500,
)
roomextra = models.ManyToManyField(
to='hotel.RoomExtra',
related_name='room_extra',
verbose_name='room extra',
)
bathroom = models.ForeignKey(
to='hotel.Bathroom',
on_delete=models.CASCADE,
)
available = models.BooleanField(default=True,)
def __str__(self):
return self.name
Adding a proxy model for Room // Room Extra allows the change of output text on the Django admin
class RoomRoomExtraProxy(Room.roomextra.through):
class Meta:
proxy = True
def __str__(self):
return self.room.name + ' // ' + self.roomextra.name

Filtering in ManytoManyField

How to make a choice only from users who are in the group created in the admin panel? In Foreign Key, this could be done via limit_choices_to, and in MtM it is not known as. Google didn't help.
class Application(models.Model):
STATUS_CHOICES = (
('In the work', 'В работе'),
('New', 'Новая'),
('Complited', 'Завершена')
)
author = models.ForeignKey(User, related_name = 'author', null = True)
title = models.CharField(max_length=50)
text = models.TextField()
room = models.CharField(max_length = 5)
published_date = models.DateField(blank=True, null=True, default = datetime.datetime.now)
status = models.CharField(max_length=15, choices=STATUS_CHOICES, default='New')
owner = models.ManyToManyField(User)
def __str__(self):
return self.title
Maybe a din't understand what you really want, but you can use limit_choices_to in a M2M field.
See the docs: https://docs.djangoproject.com/en/2.0/ref/models/fields/#manytomany-arguments

Categories

Resources