1

First of all - I understand that CharField is rather bad primary key, but it's unique in-game name, good 2 use as-is in many places, and may contain spacees. And IMHO the problem will repeat with non pkey field anyway

3 models - source, and two references. The first reference works perfectly in admin UI with the same code, the second - unworkanle during creating record

class PilotUsers(AbstractUser, PermissionsMixin):
    first_name = None
    last_name = None
    username = None

    ed_name = models.CharField(primary_key=True,max_length=60,null=False,blank=False,unique=True,verbose_name='Pilot name in Elite Dangerous', )
    squadron_tag = models.ForeignKey('Squadrons', verbose_name='Frontier squadron tag', on_delete=models.PROTECT, default='----')
    email = models.EmailField(unique=True)
    USERNAME_FIELD = 'ed_name'
    REQUIRED_FIELDS = ['email']
    objects = PilotUserManager()

    def __str__(self):
        return self.ed_name

    class Meta:
        app_label = 'common_pages'

This is working in admin UI - image below

class Cert(DetailsModel, AbstractCert):
    organizational_unit_name = models.ForeignKey('common_pages.PilotUsers', verbose_name='ED Pilot Name', on_delete=models.PROTECT)
    class Meta(AbstractCert.Meta):
        abstract = False
        swappable = swapper.swappable_setting("posts", "Cert")

enter image description here

This

class ActionFeed(models.Model):
    pkey = models.BigAutoField(primary_key=True)
    received = models.DateTimeField(verbose_name='Date-time')
    ed_name = models.ForeignKey('common_pages.PilotUsers', verbose_name='ED Pilot Name', on_delete=models.CASCADE)
#skipped
    raw_data = models.JSONField(verbose_name='Raw Data', null=False)

is unworkable during creating new record

print (f'Pilot = {pilot}')
record = ActionFeed(received= ts, ed_name=pilot, #skipped
                                           raw_data = entry)

The error is

Cannot assign "'Al L****]'": "ActionFeed.ed_name" must be a "PilotUsers" instance.

Attn - Single and double quote from each side of the name - debug printed w\o quotes at all

User is created by createsuperuser command and exactly valid - admin page login is OK. Compared names from Postgre amd input to the model byte by byte using ASCII 2 Hex conversion in case (of course w\o quotes) - exact. Something needed to be done for comparing data with spaces correctly, but no mind, what - plase, advice.

2
  • So what is pilot? A string? Commented Jul 12 at 11:37
  • string, got from JSON - some masked by * Pilot = Al L*****U] BTW, was copy-pastin it for creating superuser Commented Jul 12 at 11:41

1 Answer 1

1

ed_name can not be assigned a string, or at least not directly. You can first fetch the PilotUsers object, and then assign it, like:

print(f'Pilot = {pilot}')
pilot_instance = get_object_or_404(PilotUsers, ed_name=pilot)
record = ActionFeed(received=ts, ed_name=pilot_instance, raw_data=entry)

or you can assign it through the underlying ed_name_id here, since it is a primary key:

print(f'Pilot = {pilot}')
record = ActionFeed(received=ts, ed_name_id=pilot_instance, raw_data=entry)

Therefore it also does not make much sense to name the field ed_name: it isn't an ed_name, but a PilotUsers object.


Note: Normally a Django model is given a singular name [django-antipatterns], so PilotUser instead of PilotUsers.


Note: It is probably not a good idea to work with a primary key over which user has control [django-antipatterns]. Django does not cover the case very well, and it can have all sorts of unwanted side-effects.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks! Cannot upvote now, will, do later

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.