Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make an HerokuConnect model the app's custom user model #93

Open
Eliagandolfi opened this issue Jul 19, 2019 · 5 comments
Open

Make an HerokuConnect model the app's custom user model #93

Eliagandolfi opened this issue Jul 19, 2019 · 5 comments

Comments

@Eliagandolfi
Copy link
Contributor

I need to either extend/substitute my Django app's user model a HerokuConnect model
Specifically, vendors registered in Salesforce should be able to login with their vendor_code__c as username

#models.py
class Vendor(hc_models.HerokuConnectModel):
    sf_object_name = 'Vendor__c'

    vendor_code = hc_models.ExternalID(sf_field_name='Vendor_Code__c', unique=True, upsert=False) # this should be the username
    sf_id = hc_models.fields.ID(db_column='sfid', db_index=True, editable=False, max_length=18, sf_field_name='ID', unique=True, upsert=False)
    name = hc_models.Text(sf_field_name='Name',  max_length=80)
    email = hc_models.Text(sf_field_name='Email__c',  max_length=80)

I've tried to replicate the vendor model with multi-table inheritance (referred to this tutorial)

#models.py
class vendoruser(Vendor):
    hc_model = models.OneToOneField(Vendor, on_delete=models.CASCADE, to_field='vendor_code', parent_link=True, db_constraint=False)

The idea is to extend the model from here. I do as in the example, but I get blocked right away with the following error

salesforce.vendoruser: (heroku_connect.E006) salesforce.vendoruser.sf_object_name 'Vendor__c' clashes with another model.
        HINT: Make sure your 'sf_object_name' is correct.

I've also tried to use hc_models.OneToOneField or hc_models.ForeignKey but it's not supported. Any suggestion on how to work around this?

@codingjoe

@codingjoe
Copy link
Contributor

codingjoe commented Jul 22, 2019

Hi @Eliagandolfi thanks again for reaching out here on GitHub.
I had a quick look at the code. I am not sure it will work, but could you set Meta.managed = True on your vendoruser class?
Or could you try to set the the metaclass on your child class to the default django meta class: vendoruser(Vendor, metaclass=models.ModelBase)

@Eliagandolfi
Copy link
Contributor Author

Hi @codingjoe, really thank you so much for the quick reply.
Great, it the error is solved when setting

class Meta:
     managed = True

I'll propose a change in the source code

Still, I can't change the behaviour or my source model's field.
Specifically, I'd like to set my vendor_code` as my extended-user-model username.
That means, create as many users as many vendors in my table, with username=vendor_code
I'm trying the following

#models.py
class vendoruser(Vendor):
    hc_model = models.OneToOneField(ve, on_delete=models.CASCADE, to_field='code', parent_link=True, db_constraint=False)
    vendor_code = models.OneToOneField(User, on_delete=models.CASCADE)
    class Meta:
        managed=True

but getting this error

django.core.exceptions.FieldError: Local field 'vendor_code' in class 'vendoruser' clashes with field of the same name from base class 'Vendor'.

I've also tried to create a custom user model using AbstractUser and AbstractBaseUser but I can't figure out how to realate it with the vendoruser model above
Do you have any suggestion on how to work around this?

@codingjoe
Copy link
Contributor

@Eliagandolfi can you share the ve model too, I need the full picture to understand where the error is coming from.

@Eliagandolfi
Copy link
Contributor Author

Hi @codingjoe
So sorry for the confusion, ve was just how I renamed my vendor model.
Here's a resume of the situation:

class ve(hc_models.HerokuConnectModel):
    sf_object_name = 'Vendor__c'

    name = hc_models.Text(sf_field_name='Name',  max_length=80)
    code = hc_models.ExternalID(sf_field_name='Vendor_Code__c') # I want this to be the username of my custom user model
    sf_id = hc_models.fields.ID(db_column='sfid', db_index=True, editable=False, max_length=18, 
                                sf_field_name='ID', unique=True, upsert=False)
                                # I want this to be related to the username above in my custom user model
    zone = hc_models.Text(sf_field_name='Zone__c', max_length=80)
    active = hc_models.AnyType(sf_field_name='Active__c', max_length=80)

Here's how I'm trying to extend the ve model to make it my custom user model

class veuser(ve):
    hc_model = models.OneToOneField(ve, on_delete=models.CASCADE, to_field='code', parent_link=True, db_constraint=False)

    class Meta:
        managed=True

I need to tell Django to use code of the ve model as username. I've tried this workaround but it's not working
code = models.OneToOneField(User, on_delete=models.CASCADE)

Do you have any suggestion on how to solve the issue?

@codingjoe
Copy link
Contributor

codingjoe commented Aug 9, 2019

@Eliagandolfi I have an Idea, can you please change the veuser metaclass:

class vendoruser(Vendor, metaclass=models.ModelBase):
    # ....

I would also encourage you to look into pep8 naming conventions in Python. Make reading code for someone like me a lot simpler.
Please also drop the sfid field on the ve class. It automatically exists.

@amureki amureki transferred this issue from thermondo/django-heroku-connect-sample Jun 2, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants