Django ORM equivalent to left exclusive JOIN - sql

Relatively new to Django and I have the following models in my django (3.2) project:
class projectsA(models.Model):
projectID_A = models.BigIntegerField(primary_key=True)
project_name_A = models.TextField(blank=True, null=True)
project_desc_A = models.TextField(blank=True, null=True)
projectID_B = models.ForeignKey('projectsB', models.DO_NOTHING, db_column='projectID_B', blank=True, null=True, db_constraint=False)
class Meta:
managed = False
db_table = 'projectsA'
class projectsB(models.Model):
projectID_B = models.BigIntegerField(primary_key=True)
project_name_B = models.TextField(blank=True, null=True)
project_desc_A = models.TextField(blank=True, null=True)
class Meta:
managed = False
db_table = 'projectsB'
I want to get all projects from projectsA which are not in projectsB. The SQL equivalent would be
SELECT * FROM projectsA a LEFT JOIN projectsB b on a.projektID_B = b.projectID_B WHERE b.projectID_B is null
I have tried with .exclude or .select_related() and several other approaches, but cannot find a solution for this scenario. Thanks in advance.

It should be something like:
queryset = projectsA.objects.filter(projektID_B__isnull=True)
You can read about isnull here https://docs.djangoproject.com/en/4.0/ref/models/querysets/#isnull

Related

from sql to Django... i don't understand

i have 3 models (protocollo_pratica, protocollo_soggetto and protocollo_anaprat) and i need extract for each protocollo_pratica a list of soggetti with a specific "tipo" but i don't understand how to make this in django views. Thank you so much for your help.
`
this is my models.py :
`
from django.db import models
# Create your models here.
class Soggetto(models.Model):
cognome = models.CharField(max_length=100, null=True)
nome = models.CharField(max_length=100, null=True)
comune_nascita = models.CharField(max_length=100, null=True)
data_nascita = models.DateField(null=True)
codice_fiscale = models.CharField(max_length=16, null=True)
def __str__(self):
"""String for representing the MyModelName object (in Admin site etc.)."""
return self.nome
class Pratica(models.Model):
oggetto = models.CharField(max_length=100)
anagrafe = models.ManyToManyField(Soggetto,
through='Anaprat',
through_fields=('pratica', 'soggetto'),)
def __str__(self):
"""String for representing the MyModelName object (in Admin site etc.)."""
return self.oggetto
class Anaprat(models.Model):
tipo=models.CharField( max_length=50)
pratica=models.ForeignKey("Pratica", related_name='pratiche', on_delete=models.CASCADE)
soggetto=models.ForeignKey("Soggetto", related_name='soggetti', on_delete=models.CASCADE)
def __str__(self):
"""String for representing the MyModelName object (in Admin site etc.)."""
return f"{self.tipo, self.soggetto}"`
and this is my sql query :
`SELECT
p.id,
pa.tipo tipo,
ps.cognome,
ps.nome,
ps.data_nascita,
ps.comune_nascita
from
(SELECT
id id
from protocollo_pratica pp ) p,
protocollo_anaprat pa
left JOIN protocollo_soggetto ps
on ps.id=pa.soggetto_id
where p.id=pa.pratica_id`

Cannot resolve keyword into field error while using drf model serializer and search_fields within field set?

SerializerClass:
class VacancySerializer(serializers.ModelSerializer):
organization_small_name = serializers.CharField(source='organization.short_name', read_only=True)
class Meta:
model = Vacancy
fields = ['organization', 'description', 'specs', 'type', 'publication_date',
'is_published', 'withdrawal_data', 'organization_small_name', ]
read_only_fields = ['publication_date', 'is_published', 'withdrawal_data',]
ViewSet:
class VacancyViewSet(viewsets.ModelViewSet):
queryset = Vacancy.objects.all()
serializer_class = VacancySerializer
filter_backends = [filters.SearchFilter]
search_fields = ['organization_small_name']
...
Model:
class Vacancy(models.Model):
organization = models.OneToOneField(DictOrganization, on_delete=models.CASCADE, related_name='vacancies')
description = models.TextField('Описание')
specs = models.ManyToManyField(DictSpec, blank=True)
type = models.CharField('Тип', max_length=20, choices=VacancyType.choices(), default=VacancyType.PRACTICE.value)
publication_date = models.DateField('Дата публикации', null=True, blank=True)
is_published = models.BooleanField('Опубликовано', default=False)
withdrawal_data = models.DateField('Дата снятия с публикации', null=True, blank=True)
My goal is to make API search by 'organization_small_name' field
that is in VacancySerializer.
Server runs successfully, but as soon as i add ?search parameter, i get next error:
Why it doesn't recognize 'organization_small_name' field, even thought it is decribed in serializer, and how can i fix it?

Django Model Design (Big model vs multiple)

I have a question about designing my models. Suppose I have a following model:
class Comment(models.Model):
who = models.ForeignKey(User, on_delete=models.CASCADE)
created = models.DateTimeField(auto_now_add=True)
text = models.CharField(max_length=1000)
likes = models.IntegerField(default=0)
parent_comment = models.ForeignKey('self', on_delete=models.CASCADE, null=True, related_name='child_comments')
Now I would like models for multiple topics (ShoppingList, Games,...). I came to two possible solutions and need help with deciding more suitable one.
1) Make Comment abstract and extend it for every new model wanted.
class ShoppingListComment(Comment):
shopping_list = models.ForeignKey(ShoppingList, related_name='shopping_comments', on_delete=models.CASCADE)
I could then query this game comments with something like:
ShoppingListComment.objects.all()
2) Add extra nullable Foreing keys directly to comment:
class BigCommentModel(models.Model):
who = models.ForeignKey(User, on_delete=models.CASCADE)
created = models.DateTimeField(auto_now_add=True)
text = models.CharField(max_length=1000)
likes = models.IntegerField(default=0)
parent_comment = models.ForeignKey('self', on_delete=models.CASCADE, null=True, related_name='child_comments')
shopping_list = models.ForeignKey(ShoppingList, related_name='shopping_comments', on_delete=models.CASCADE, null=True),
game = models.ForeignKey(Game, related_name='game_comments', on_delete=models.CASCADE, null=True)
I could then query this game comments with something lile:
BigCommentModel.objects.filter(game__isnull=False)

Django rest framework reverse relation serializers exclude fields

I have two models Question and Options
class Question(models.Model):
question_identifier = models.CharField(max_length=255)
question_text = models.TextField(blank=False)
question_category = models.ManyToManyField('Category')
question_tags = models.CharField(max_length=255, blank=True)
class Options(models.Model):
question = models.OneToOneField('Question', related_name='options', blank=False, null=False)
option1 = models.CharField(max_length=255,blank=False,null=True)
option2 = models.CharField(max_length=255,blank=False,null=True)
option3 = models.CharField(max_length=255,blank=True,null=True)
option4 = models.CharField(max_length=255,blank=True,null=True)
I have written a serializer for Question model which serializes options as well (reverse relation). I want to omit the question field from the Options? Is there a way to achieve this?
My Question Serializer:-
class QuestionSerializer(serializers.ModelSerializer):
"""
Serializer for Question object from qna.models
"""
question_category = CategorySerializer(many=True,write_only=True)
class Meta:
model = Question
fields = ('id', 'options', 'question_identifier','question_text','question_tags','question_category')
depth = 1
You can achieve that by creating a separate serializer for an Options model.And use it instead of default field, without depth value.
class OptionsSerializer(serializers.ModelSerializer):
class Meta:
model = Options
fields = ('option1', 'option2', 'option3')
class QuestionSerializer(serializers.ModelSerializer):
question_category = CategorySerializer(many=True,write_only=True)
options = OptionsSerializer()
class Meta:
model = Question
fields = ('id', 'options', 'question_identifier','question_text','question_tags','question_category')

Issue with complex Django join query

I can't find a valid way with Django OMR in order to get : ( a raw query is also fine )
the Sites.sitename which made the Analysis where (Analysi_Items.name='somename' and Analysis_Items.value='somevalue') and (Analysi_items_name='somename' and Analysis_Items.value='somevalue') and (Analysis_items.name='somename' and Analysis_Items.value='somevalue').
class Sites(models.Model):
region = models.CharField(max_length=1000)
province = models.CharField(max_length=1000)
sitename = models.CharField(max_length=1000, primary_key=True)
class Meta:
verbose_name_plural = "Sites"
def __unicode__(self):
return self.sitename
class Analysis_Items(models.Model):
code = models.ForeignKey('Analysis')
name = models.CharField(max_lenght=100)
value = models.CharField(max_length=20)
class Meta:
verbose_name_plural = "Analysis Type"
class Analysis(models.Model):
date = models.DateField()
site = models.ForeignKey('Sites')
def __unicode__(self):
return str(self.date)
class Meta:
verbose_name_plural = "Analysis"
Hope this is clear enough. thank you in advance!
Site.objects.filter(analysis__analysis_items__name='some_name', analysis__analysis_items__value='some_value')
You can keep adding additional parameters in the same keep AND'ing them all together.