Question: Calendars have a owner and have a `ManyToMany` field 'assistants'
i have a Calendar who has 2 assistants one of which is its owner.
I think these 3 lines of code in the django shell can explain the weird behaviour quite well.

```py
In [17]: Calendar.objects.filter(assistants=customer).exclude(owner=customer)                             
Out[17]: <QuerySet []>
In [20]: Calendar.objects.filter(owner=customer)                                                          
Out[20]: <QuerySet [<Calendar: aliz cal>, <Calendar: yassi has a calendar>]>
In [19]: Calendar.objects.filter(owner=customer) | Calendar.objects.filter(assistants=customer).exclude(owner=customer)                                                                                    
Out[19]: <QuerySet [<Calendar: aliz cal>, <Calendar: aliz cal>, <Calendar: yassi has a calendar>]>

```

Of course expected the result of queryset join to be the actual union of them.

Answer: 
Assuming this is for django 1.11+:  

`|` does not represent a union. It represents an OR-combination (which maintains **all** joins; hence aliz showing up twice) of two querysets .

`qs1.filter(x=1) | qs2.exclude(x=1)` translates to:

```
SELECT STUFF FROM TABLES_AND_JOINS WHERE (x = 1 OR NOT (x = 1))

```

While `qs1.filter(x=1).union(qs2.exclude(x=1))` translates to:

```
SELECT STUFF FROM TABLE1 WHERE x = 1 UNION SELECT STUFF FROM TABLE2 WHERE NOT x = 1

```

Use `str(qs.query)` to see the SQL.
What you are doing is `OR`-ing the `WHERE` clauses of both queries, which is different from a union (and a bit tricky when joining is involved; here, the ORM switches from an inner join in queryset #1 to an outer join in queryset #3 to account for the second query that has no joins). See the relevant [docs](https://docs.djangoproject.com/en/2.1/ref/models/querysets/#or).

Try [`union()`](https://docs.djangoproject.com/en/2.1/ref/models/querysets/#union), available from Django 1.11 onwards:

```
qs1 = Calendar.objects.filter(assistants=customer).exclude(owner=customer)                             
qs2 = Calendar.objects.filter(owner=customer) 
qs3 = qs1.union(qs2)

```