Django ORM equivalent - sql

I have the following code in a view to get some of the information on the account to display. I tried for hours to get this to work via ORM but couldn't make it work. I ended up doing it in raw SQL but what I want isn't very complex. I'm certain it's possible to do with ORM.
In the end, I just want to populate the dictionary accountDetails from a couple of tables.
cursor.execute("SELECT a.hostname, a.distro, b.location FROM xenpanel_subscription a, xenpanel_hardwarenode b WHERE a.node_id = b.id AND customer_id = %s", [request.user.id])
accountDetails = {
'username': request.user.username,
'hostname': [],
'distro': [],
'location': [],
}
for row in cursor.fetchall():
accountDetails['hostname'].append(row[0])
accountDetails['distro'].append(row[1])
accountDetails['location'].append(row[2])
return render_to_response('account.html', accountDetails, context_instance=RequestContext(request))

It would be easier if you post models. But from SQL I'm assuming the models are like this:
class XenPanelSubscription(models.Model):
hostname = models.CharField()
distro = models.CharField()
node = models.ForeignKey(XenPanelHardwareNode)
customer_id = models.IntegerField()
class Meta:
db_table = u'xenpanel_subscription'
class XenPanelHardwareNode(models.Model):
location = models.CharField()
class Meta:
db_table = u'xenpanel_hardwarenode'
Based on these models:
accountDetails = XenPanelSubscription.objects.filter(customer_id = request.user.id)
for accountDetail in accountDetails:
print accountDetail.hostname, accountDetail.distro, accountDetail.node.location

Related

Django restframework SerializerMethodField background work

I am writing a project in Django with rest framework by using SerializerMethodField. This method makes queries for every row to get data, or View collects all queries and send it to DB? Django can make it as one joint query?
class SubjectSerializer(serializers.ModelSerializer):
edu_plan = serializers.SerializerMethodField(read_only=True)
academic_year_semestr = serializers.SerializerMethodField(read_only=True)
edu_form = serializers.SerializerMethodField(read_only=True)
def get_edu_plan(self, cse):
return cse.curriculum_subject.curriculum.edu_plan.name
def get_academic_year_semestr(self, cse):
semester = cse.curriculum_subject.curriculum.semester
return {'academic_year': semester.academic_year, 'semester': semester}
def get_edu_form(self, cse):
return cse.curriculum_subject.curriculum.edu_form.name
class Meta:
model = CurriculumSubjectEmployee
fields = [
'id',
'name',
'edu_plan',
'academic_year_semestr',
'edu_form'
]
class SubjectViewSet(viewsets.ReadOnlyModelViewSet):
serializer_class = SubjectSerializer
def get_queryset(self):
contract = self.request.user.employee.contract
if contract is None:
raise NotFound(detail="Contract not found", code=404)
department = contract.department
cses = CurriculumSubjectEmployee\
.objects\
.filter(curriculum_subject__department=department)
return cses

SQL Query logic to Django ORM Query logic

I have tried to think about how the following SQL query would be structured as a Django ORM query but I have had no luck in my multiple attempts. Can anyone help?
SELECT targets_genetarget.gene, count(targets_targetprediction.gene) as total
FROM targets_genetarget
LEFT OUTER JOIN targets_targetprediction on targets_targetprediction.gene =
targets_genetarget.gene
WHERE list_name LIKE %s
GROUP BY targets_genetarget.gene
class GeneTarget(models.Model):
list_name = models.CharField(max_length=100)
gene = models.CharField(max_length=50)
date_added = models.DateField(auto_now=True)
class Meta:
unique_together = (('list_name', 'gene'),)
def __str__(self):
return self.list_name
class TargetPrediction(models.Model):
specimen_id = models.CharField(max_length=100)
patient_peptide = models.ForeignKey(Peptide, on_delete=models.CASCADE, verbose_name="Peptide", related_name="predictions")
allele = models.ForeignKey(Allele, on_delete=models.CASCADE, verbose_name="Allele", related_name="predictions")
gene = models.CharField(max_length=50)
class Meta:
unique_together = (('specimen_id', 'patient_peptide', 'allele', 'gene'),)
def get_absolute_url(self):
return f'/samples/specid-{self.specimen_id}'
def __str__(self):
return (f'Specimen: {self.specimen_id} Peptide: {self.patient_peptide} Allele: {self.allele} Gene: {self.gene} ')
There's nothing stopping you declaring the TargetPrediction.gene field as a foreign key using the to_field attribute, so you wouldn't need to change the data at all:
class TargetPrediction(models.Model):
...
gene = models.ForeignKey("GeneTarget", to_field="gene")
Now your query simply becomes:
GeneTarget.objects.filter(list_name="whatever").values("gene").annotate(total=Count("targetprediction"))

get count from related table data in django rest framework

I have two tables
class student(models.Model):
frist_name = models.CharField(max_length=255)
last_name = models.CharField(max_length=255)
class subject(models.Model):
student = models.ForeignKey(student)
sub_name = models.CharField()
I want student list and subject count in serializer
my serializer
classs SubjectSerializers(serializers.ModelSerializer):
class Meta:
model = JobPosting
fields = ('id','sub_name')
class StudentSerializers(serializers.ModelSerializer):
sub = SubjectSerializers(source = 'student')
class Meta:
model = JobPosting
fields = ('id','first_name', 'last_name','sub')
How can i get subject count for every student in serializer, Now i am geting subject table data but i want count like this
"detail": [{
"id": 680,
"first_name": "riya",
"last_name": "tri",
"subject_count": 5
}],
You can achieve this by using a serializer method field
Then StudentSerializer becomes the following:
class StudentSerializers(serializers.ModelSerializer):
sub = SubjectSerializers(source = 'student')
subject_count = serializers.SerializerMethodField()
class Meta:
model = JobPosting
fields = ('id','first_name', 'last_name','sub')
def get_subject_count(self, student):
return Subject.objects.filter(student=student).count()

Grails query to filter on association and only return matching entities

I have the following 1 - M (one way) relationship:
Customer (1) -> (M) Address
I am trying to filter the addresses for a specific customer that contain certain text e.g.
def results = Customer.withCriteria {
eq "id", 995L
addresses {
ilike 'description', '%text%'
}
}
The problem is that this returns the Customer and when I in turn access the "addresses" it gives me the full list of addresses rather than the filtered list of addresses.
It's not possible for me to use Address.withCriteria as I can't access the association table from the criteria query.
I'm hoping to avoid reverting to a raw SQL query as this would mean not being able to use a lot functionality that's in place to build up criteria queries in a flexible and reusable manner.
Would love to hear any thoughts ...
I believe the reason for the different behavior in 2.1 is documented here
Specifically this point:
The previous default of LEFT JOIN for criteria queries across associations is now INNER JOIN.
IIRC, Hibernate doesn't eagerly load associations when you use an inner join.
Looks like you can use createAlias to specify an outer join example here:
My experience with this particular issue is from experience with NHibernate, so I can't really shed more light on getting it working correctly than that. I'll happily delete this answer if it turns out to be incorrect.
Try this:
def results = Customer.createCriteria().listDistinct() {
eq('id', 995L)
addresses {
ilike('description', '%Z%')
}
}
This gives you the Customer object that has the correct id and any matching addresses, and only those addresses than match.
You could also use this query (slightly modified) to get all customers that have a matching address:
def results = Customer.createCriteria().listDistinct() {
addresses {
ilike('description', '%Z%')
}
}
results.each {c->
println "Customer " + c.name
c.addresses.each {address->
println "Address " + address.description
}
}
EDIT
Here are the domain classes and the way I added the addresses:
class Customer {
String name
static hasMany = [addresses: PostalAddress]
static constraints = {
}
}
class PostalAddress {
String description
static belongsTo = [customer: Customer]
static constraints = {
}
}
//added via Bootstrap for testing
def init = { servletContext ->
def custA = new Customer(name: 'A').save(failOnError: true)
def custB = new Customer(name: 'B').save(failOnError: true)
def custC = new Customer(name: 'C').save(failOnError: true)
def add1 = new PostalAddress(description: 'Z1', customer: custA).save(failOnError: true)
def add2 = new PostalAddress(description: 'Z2', customer: custA).save(failOnError: true)
def add3 = new PostalAddress(description: 'Z3', customer: custA).save(failOnError: true)
def add4 = new PostalAddress(description: 'W4', customer: custA).save(failOnError: true)
def add5 = new PostalAddress(description: 'W5', customer: custA).save(failOnError: true)
def add6 = new PostalAddress(description: 'W6', customer: custA).save(failOnError: true)
}
When I run this I get the following output:
Customer A
Address Z3
Address Z1
Address Z2

django left join with null

The model:
class Product(models.Model):
name = models.CharField(max_length = 128)
def __unicode__(self):
return self.name
class Receipt(models.Model):
name = models.CharField(max_length=128)
components = models.ManyToManyField(Product, through='ReceiptComponent')
class Admin:
pass
def __unicode__(self):
return self.name
class ReceiptComponent(models.Model):
product = models.ForeignKey(Product)
receipt = models.ForeignKey(Receipt)
quantity = models.FloatField(max_length=9)
unit = models.ForeignKey(Unit)
def __unicode__(self):
return unicode(self.quantity!=0 and self.quantity or '') + ' ' + unicode(self.unit) + ' ' + self.product.genitive
The idea:
there are a components on stock. I'd like to find out which recipes I can made with components which I have.
It's not easy - but possible - I made a SQL view, which gets the solution. But I'm learning python and Django so I'd like to make it Django-style ;D
The concept of solution:
get the set of recipes which has at last one component:
list_of_available_components = ReceiptComponent.objects.filter(product__in=list_of_available_products).distinct()
list_of_related_receipts = Receipt.objects.filter(receiptcomponent__in = list_of_available_components).distinct()
get recipes (from list_of_related_receipts) which has not at last one component
list_of_incomplete_recipes = (SELECT * FROM drinkbook_receiptcomponent LEFT JOIN drinkstore_stock_products USING(product_id) WHERE drinkstore_stock_products.stock_id IS NULL AND receipt_id IN (SELECT receipt_id FROM drinkbook_receiptcomponent JOIN drinkstore_stock_products USING(product_id)))
get recipes (from list_of_related_receipts) which are not in "list_of_incomplete_recipes"
Heh. How stupid am I. This could be solved much easier. I don't have to find receipes which have at least one component. I can (the same way!) find recipes which i can't do because there is at least one component which i DON'T have.
list_of_unavailable_components = ReceiptComponent.objects.exclude(product__in=list_of_available_products).distinct()
And now.
list_of_available_receipts = Receipt.objects.exclude(receiptcomponent__in = list_of_unavailable_components).distinct()
Simple and clean. Thank you for cooperation ;D