Repository: django-salesforce/django-salesforce (language: python)

Issue:
Error on update Foreign Key (AccountId)
Hi, when trying to update the FK I get the following error:
```
Contact.objects.filter(...).update(account=Account.objects.get(...))
```
`salesforce.dbapi.exceptions.SalesforceError: INVALID_FIELD_FOR_INSERT_UPDATE
    Account: bad field names on insert/update call:  AccountId
    FIELDS: [' AccountId']`
    
I'm trying to change the "account" field of the Contact to another, but without success.
``` python
class Contact(models.Model):
    ...
    account = models.ForeignKey('Account', models.DO_NOTHING, blank=True, null=True)
    ...
```
The models have been obtained with inspectdb.
 


Discussion / hints:
I can not reproduce this error with the current django-salesforce v3.2 neither with the newest Django 3.2 or with the oldest supported Django 2.0.

Please specify the versions of both packages. Write also the type of conditions in the filter and verify that the Account field of Contact can be updated by a normal `.save()` method. Maybe your organization have a validation rule installed on Contact that is triggered on Contact update. (The condition in `Account.objects.get(...)` is not important because it is resolved completely before `update(...)`, but maybe some Account can't be assigned due to your business logic rules.)

---
I found a different bug in a case `Contact.objects.filter(account=None).update(account=some_account)`.
It can be easily bypassed by `Contact.objects.filter(account_id='').update(account=some_account)`.
However I will try to fix that special case, even that it could be found finally as an edge case bug in Django. 
The error "SalesforceError: INVALID_FIELD_FOR_INSERT_UPDATE" can be reproduced if the logged user does not have the "Edit Access" permission for the "Account Name" field of "Contact" object. That is self-evident.

Fix patch:
diff --git a/salesforce/backend/models_lookups.py b/salesforce/backend/models_lookups.py
index 5e4bb8bce..15a73c1c4 100644
--- a/salesforce/backend/models_lookups.py
+++ b/salesforce/backend/models_lookups.py
@@ -9,6 +9,8 @@
 class IsNull(models.lookups.IsNull):
     def override_as_sql(self, compiler, connection):  # pylint:disable=unused-argument
         # it must be relabeled if used for a children rows set
+        if compiler.soql_trans is None:
+            compiler.get_from_clause()
         sql, params = compiler.compile(self.lhs.relabeled_clone(compiler.soql_trans))
         return ('%s %s null' % (sql, ('=' if self.rhs else '!='))), params
 


Test patch:
diff --git a/salesforce/tests/test_integration.py b/salesforce/tests/test_integration.py
index e7c0ab59b..07c4990b7 100644
--- a/salesforce/tests/test_integration.py
+++ b/salesforce/tests/test_integration.py
@@ -586,6 +586,16 @@ def test_queryset_update(self) -> None:
             account_0.delete()
             account_1.delete()
 
+    @skipUnless(default_is_sf, "Default database should be any Salesforce.")
+    def test_queryset_update_foreign_key(self) -> None:
+        contact = Contact.objects.exclude(account=None)[0]
+        Contact.objects.filter(Id=contact.Id).update(account=contact.account)
+
+    @skipUnless(default_is_sf, "Default database should be any Salesforce.")
+    def test_queryset_none_filter_update(self) -> None:
+        """Test that this can be compiled and the SOQL is valid"""
+        Contact.objects.filter(pk=None).update(last_name='a')
+
     @skipUnless(default_is_sf, "Default database should be any Salesforce.")
     def test_bulk_delete_and_update(self) -> None:
         """Delete two Accounts by one request.