2

I have the following models:

class Employee(models.Model):

    def getFullname(self):
        return '{}, {} {}'.format(self.empLastname,self.empFirstname, self.empMiddlename)

    empID = models.CharField(primary_key=True, max_length= 50, null=False)
    empLastname = models.CharField(max_length=50)
    empFirstname = models.CharField(max_length=50)
    empMiddlename = models.CharField(max_length=50, null=True)
    fullname = property(getFullname)

    def __str__(self):
       return self.fullname

class Picture(models.Model):
    empID = models.ForeignKey(Employee, related_name="pictures", to_field='empID', on_delete = models.CASCADE)
    picture = models.ImageField('Uploaded image')
    isDef = models.BooleanField(default=False)

I want to query for all employee where isDefault=True in the Picture model. But not all Employee had pictures. So basically I want to query all Employee which isDefault=True and all Employee that have no picture(s).

My query is look like this:

SELECT manager_employee.`*`, manager_picture.*
FROM manager_employee
LEFT JOIN manager_picture ON (manager_employee.empID = manager_picture.empID_id
AND manager_picture.isDef)

serializer.py

class PictureSerializer(serializers.ModelSerializer):
      class Meta:
            model = Picture
            fields = (
                  'empID',
                  'picture',
                  'isDef'
            )

class EmployeeListSerializer(serializers.ModelSerializer):
      pictures = PictureSerializer(many = True, read_only = True)

      class Meta:
            model = Employee
            fields = (
                  'empID',
                  'empLastname',
                  'empFirstname',
                  'empMiddlename',
                  'fullname',
                  'pictures'
            )

This query gave me the correct result.. The problem is on how to do it in Django..

Suppose I have a record of Employee model

=============================================================================
empID    | empLastname    | empFirstname  | empMiddlename | fullname        |
=============================================================================
  1      | Doe            | John          | Smith         | Doe, John Smith |
-----------------------------------------------------------------------------
  2      | Potter         | Harry         | Moon          | Potter, Harry ..|
-----------------------------------------------------------------------------
  3      | Aaaa           | Abbb          | Accc          | ...             |
-----------------------------------------------------------------------------
  4      | Baaaa          | Bbbb          | Bccc          | ...             |
-----------------------------------------------------------------------------

now in Picture model

================================================
empID     | Picture                   | isDef  |
================================================
  1       | Pic1.jpg                  | 0      |
------------------------------------------------
  1       | Pic2.jpg                  | 0      |
------------------------------------------------
  1       | Pic3.jpg                  | 1      | *which makes this as default*
------------------------------------------------
  2       | emp2Pic1.jpg              | 1      | *which makes this as default*
------------------------------------------------
  2       | emp2Pic2.jpg              | 0      |
------------------------------------------------
  4       | emp4Pic1.jpg              | 0      |
------------------------------------------------
  4       | emp4Pic2.jpg              | 1      | *which makes this as default*
------------------------------------------------

now when i try this SQL:

SELECT manager_employee.`*`, manager_picture.*
    FROM manager_employee
    LEFT JOIN manager_picture ON (manager_employee.empID = manager_picture.empID_id
    AND manager_picture.isDefault)

this give me a result:

=========================================================================
empID | empLastname | empFirstname | empMiddle | Picture      | isDef   |
 1    | Doe         | John         | Smith     | Pic2.jpg     | 1       |
 2    | Potter      | Harry        | Moon      | emp2Pic1.jpg | 1       |
 3    | Aaaa        | Abbb         | Accc      | (null)       | (null)  |
 4    | Baaaa       | Bbbb         | Bccc      | emp4Pic2.jpg | 1       |
-------------------------------------------------------------------------

How to I implement this in Django?

Please somebody help me.. TIA..

N0LrAm
  • 53
  • 8
  • check this http://stackoverflow.com/questions/21271835/left-join-django-orm – Piyush S. Wanare Nov 21 '16 at 08:05
  • @PiyushS.Wanare I checked the link. but the answer is LEFT OUTER JOIN not LEFT JOIN. When I test the answer, it gave me nothing.. – N0LrAm Nov 21 '16 at 08:51
  • 1
    `Picture.objects.filter(isDefault=True,picture__isnull=True)` is this are you looking for? This will give you all employee from Picture models for whom isDefault = True and has no picture. – Piyush S. Wanare Nov 21 '16 at 09:21
  • BDW which database are you working on? – Piyush S. Wanare Nov 21 '16 at 09:27
  • I just edited my post man, and I included the `serializer.py`.. Maybe I got a problem with `serializer.py` but i just don't know what.. And I already tried the `Picture.objects.filter(isDefault=True,picture__isnull=True)` but it gave me an error `django.core.exceptions.FieldError: Cannot resolve keyword 'isDefault' into field. Choices are: empFirstname, empID, empLastname, empMiddlename, pictures`.. Im using `MySQL` – N0LrAm Nov 21 '16 at 09:33
  • @N0LrAm looking at the error message, I think you didn't write `Picture.objects.filter`, but `Employee.objects.filter`. – Назар Топольський Nov 21 '16 at 09:35
  • May be you can't keep isDefault as a column because may it's django's standard parameter so it ill skip it, try to change the column name, migrate it again and then run the query. – Piyush S. Wanare Nov 21 '16 at 09:36
  • @PiyushS.Wanare I already change the `isDefault` to `isDef`.. but still no luck.. – N0LrAm Nov 21 '16 at 09:59
  • @НазарТопольський I used `Employee.objects.filter` because I want to get all Employee data that `isDefault=True` and all Employee data that do not have any pictures.. Therefore, those pictures that is `isDefault=False` will not be listed in my query result. – N0LrAm Nov 21 '16 at 09:59
  • Then whats the problem now? What error are you getting?can you post it? – Piyush S. Wanare Nov 21 '16 at 10:00
  • `django.core.exceptions.FieldError: Cannot resolve keyword 'isDef' into field. Choices are: empFirstname, empID, empLastname, empMiddlename, pictures`... I just don't know what my problem is. Maybe in my `serializer` or the structure of my `model`..I just want to implement `LEFT JOIN`... sorry for the trouble man.. – N0LrAm Nov 21 '16 at 10:10
  • Once again: `Choices are: empFirstname, empID, empLastname, empMiddlename, pictures`. This strongly suggests you are trying to filter `Employee` since those are the fields of that model. – Назар Топольський Nov 21 '16 at 11:18
  • @НазарТопольський yes man, i got you..but if I use `Picture.objects.filter` instead of `Employee.objects.filter`, the query result will be all pictures only without the employee data.. – N0LrAm Nov 21 '16 at 13:00
  • I think you this is an XY problem. If you only need the results of that and only query - you can just go raw SQL. Either clarify **why** do you need to make that query and what exactly do you expect to get, or we won't be able to help you. – Назар Топольський Nov 21 '16 at 17:04
  • @НазарТопольський thanks for the reply bro... I just edited my post with examples. Hopefully you'll get my point.. – N0LrAm Nov 21 '16 at 17:07
  • Once again - question is as follows: what are you going to do with the results? What exactly do you need, in ORM terms? `Employee` instances? `Picture` instances? Or do you need the information as tuples/dictionaries? – Назар Топольський Nov 21 '16 at 17:10
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/128638/discussion-between-n0lram-and--). – N0LrAm Nov 21 '16 at 17:10

1 Answers1

0

Django provides you the ORM so you dont have to write your SQL. Check this : Django queryset API reference .

Also if you want to check how your Django query looks in SQL. you can try like this in django shell terminal:

>>> queryset = MyModel.objects.all()
>>> print queryset.query
SELECT "myapp_mymodel"."id", ... FROM "myapp_mymodel"
Kishan Mehta
  • 2,598
  • 5
  • 39
  • 61
  • Thanks for the reply man.. I did not wrote the SQL...I just used it to check if my requirements are correct, that is why I post the sample query. The only problem is that I don't know how to do it in Django. I know that ModelName.Objects.all() is look like "SELECT * FROM ModelName".. I don't know how to perform LEFT JOIN in Django. Hope you get my point.. My problem is what would be the views.py or the serializers.py look like. – N0LrAm Nov 21 '16 at 07:43
  • 1
    This is not exactly what the op want – Shift 'n Tab Nov 21 '16 at 08:25