Search code examples
pythondjangodjango-modelsdjango-signals

Maintaining Relationships Between Models that are Filled Through Signals After Saving


Look at answers to see how I solved it and what my problem was :)

I have a base model called stars that contains most relationships with other models, and some of the other models are taken through a signal to perform certain scripts that will enter into the database more information about the base model. My problem is when running the signals, I don't know how to maintain relationships with the models that are already a one to one field of the base model. If I try to make the empty models used for a signal a foreign key of their instance, it gives me errors since their instance is already connected to stars through its own foreign key. I'll post part of my code here, first part of my models, and then the part of my signal:

from django.db import models

# Create your models here.

'''define table with star name and its found relationships in the cards'''

class Star(models.Model):
	name = models.CharField(max_length=100, unique = True, verbose_name = "Star Name")
	
	def __str__(self):
		return self.name


class RA(models.Model):
	name = models.OneToOneField(Star,default = 1,to_field = "name")
	Ra = models.CharField(max_length = 10, help_text=("<h4> <i> e.g. if the RA is 1 hour, 44 minutes, and 38 seconds, input the RA in this manner: <b> 014438 </b> </i> </h4>"), verbose_name = "RA", unique = True)
	def __str__(self):
		return self.Ra


class DEC(models.Model):
	name = models.OneToOneField(Star,default = 1,to_field = "name")
	Dec = models.CharField(max_length = 10, help_text=("<h4> <i> e.g if the DEC is +3 degrees, and 48.6 arc-minutes, input the DEC in this manner: <b> +0348.6 </b> DON'T FORGET THE 0s FOR ONE DIGIT INPUTS. </i> <h4>"), verbose_name = "DEC", unique = True)
	def __str__(self):
		return self.Dec


class RAnew(models.Model):
	ra_new = models.CharField(max_length = 10)
	class Meta:
		verbose_name = "new RA"

	def __str__(self):
		return self.ra_new


class DECnew(models.Model):
	dec_new = models.CharField(max_length = 10)
	class Meta:
		verbose_name = "new Dec"

	def __str__(self):
		return self.dec_new


from .signals import perform_and_save_query, clean_URL, separate_ra, separate_dec
#this connects the astroquery and other signals and runs them yay

The signal script:

#create signals to run scripts

from astroquery.simbad import Simbad
from .models import Aliases, ReferenceURL, Bibcode, RA, DEC, RAnew, DECnew, Star
from django.dispatch import receiver
from django.db.models.signals import post_save
from django.core.exceptions import ValidationError

@receiver(post_save, sender=RA)

def separate_ra(sender, **kwargs):
    if kwargs.get('created', False):
        RA.objects.get_or_create(Ra=kwargs.get('instance'))
        z = kwargs['instance']
        z = str(z)
        if len(z) < 6:
            raise ValidationError({'Ra': ["The RA needs to be 6 characters long, make sure you're using 0s in one digit pairs of numbers.",]})
        else:
            makenew = z[:2]+' h '+z[2:4]+' m '+z[4:]+' s'
            d = RAnew(ra_new = makenew)
            d.save()

@receiver(post_save, sender = DEC)

def separate_dec(sender, **kwargs):
    if kwargs.get('created', False):
        DEC.objects.get_or_create(Dec=kwargs.get('instance'))
        j = kwargs['instance']
        j = str(j)
        if len(j) < 7:
            raise ValidationError({'Dec': ["The Dec needs to be greater than 7 characters long, use zeros for 1 digit numbers and .0 in case of no decimals at the end",]})
        else:
            makenewdec = j[:3]+' degrees '+j[3:]+' arcmin'
            e =DECnew(dec_new = makenewdec)
            e.save()

The only signal that maintains a relationship to its instance is the first one "perform and save query" since it deals directly with the model "stars". Is there a way that the new saved "bibcode", "New RA" and "New Dec" can maintain their relationship to either their instance or their star?


Solution

  • I was forgetting the format " model.objects.get(field = x) " to save an object for the other signals and that's why I was getting an error. I thought it had to do with the fact that the models were foreign keys of stars but it was just a syntax error!

    To add to this, I recently learned of regex validators for models, this removes my need to have a signal that validates the way an entry is written because regex validators can really deal head-on with that type of need. I highly recommend it!