CASCADE fixes in data model

This commit is contained in:
Philip Sargent 2023-03-06 16:37:38 +00:00
parent ccfc44a423
commit 94e145adce
5 changed files with 56 additions and 24 deletions

View File

@ -59,6 +59,9 @@ class Area(TroggleModel):
class CaveAndEntrance(models.Model):
"""CASCADE means that if the cave or the entrance is deleted, then this CaveAndEntrance
is deleted too
"""
cave = models.ForeignKey("Cave", on_delete=models.CASCADE)
entrance = models.ForeignKey("Entrance", on_delete=models.CASCADE)
entrance_letter = models.CharField(max_length=20, blank=True, null=True)
@ -240,6 +243,8 @@ class Cave(TroggleModel):
class EntranceSlug(models.Model):
"""If the Entrance is deleted, then this EntranceSlug is deleted too
"""
entrance = models.ForeignKey("Entrance", on_delete=models.CASCADE)
slug = models.SlugField(max_length=50, unique=True)
primary = models.BooleanField(default=False)

View File

@ -17,7 +17,9 @@ todo = """
class CaveSlug(models.Model):
"""Moved here to avoid nasty cyclic import error"""
"""Moved here to avoid nasty cyclic import error
CASCADE means that if the Cave is deleted, this is too
"""
cave = models.ForeignKey("Cave", on_delete=models.CASCADE)
slug = models.SlugField(max_length=50, unique=True)
@ -25,12 +27,13 @@ class CaveSlug(models.Model):
class LogbookEntry(TroggleModel):
"""Single parsed entry from Logbook"""
"""Single parsed entry from Logbook
Gets deleted if the Expedition gets deleted"""
date = (
models.DateField()
) # MJG wants to turn this into a datetime such that multiple Logbook entries on the same day can be ordered.ld()
expedition = models.ForeignKey(Expedition, blank=True, null=True, on_delete=models.SET_NULL) # yes this is double-
expedition = models.ForeignKey(Expedition, blank=True, null=True, on_delete=models.CASCADE) # yes this is double-
title = models.CharField(max_length=200)
cave_slug = models.SlugField(max_length=50, blank=True, null=True)
place = models.CharField(
@ -84,6 +87,9 @@ class LogbookEntry(TroggleModel):
class PersonLogEntry(TroggleModel):
"""Single Person going on a trip, which may or may not be written up.
It could account for different T/U for people in same logbook entry.
CASCADE means that if the personexpedition or the logbookentry is deleted,
then this PersonLogEntry is deleted too
"""
personexpedition = models.ForeignKey("PersonExpedition", null=True, on_delete=models.CASCADE)

View File

@ -12,7 +12,11 @@ from django.urls import reverse
class SurvexDirectory(models.Model):
path = models.CharField(max_length=200)
"""This relates a Cave to the primary SurvexFile which is the 'head' of the survex tree for
that cave. Surely this could just be a property of Cave ? No. Several subdirectories
all relate to the same Cave
"""
path = models.CharField(max_length=200)
cave = models.ForeignKey("Cave", blank=True, null=True, on_delete=models.SET_NULL)
primarysurvexfile = models.ForeignKey(
"SurvexFile", related_name="primarysurvexfile", blank=True, null=True, on_delete=models.SET_NULL
@ -66,7 +70,10 @@ class SurvexFile(models.Model):
class SurvexStationLookUpManager(models.Manager):
"""Don't know what this does,
https://docs.djangoproject.com/en/dev/topics/db/managers/"""
https://docs.djangoproject.com/en/dev/topics/db/managers/
This changes the .objects thinggy to use a case-insensitive match name__iexact
so that now SurvexStation.objects.lookup() works as a case-insensitive match
"""
def lookup(self, name):
blocknames, sep, stationname = name.rpartition(".")
return self.get(block=SurvexBlock.objects.lookup(blocknames), name__iexact=stationname)
@ -75,7 +82,7 @@ class SurvexStationLookUpManager(models.Manager):
class SurvexStation(models.Model):
name = models.CharField(max_length=100)
block = models.ForeignKey("SurvexBlock", null=True, on_delete=models.SET_NULL)
objects = SurvexStationLookUpManager()
objects = SurvexStationLookUpManager() # overwrites SurvexStation.objects
x = models.FloatField(blank=True, null=True)
y = models.FloatField(blank=True, null=True)
z = models.FloatField(blank=True, null=True)
@ -101,18 +108,22 @@ class SurvexStation(models.Model):
#
# Single SurvexBlock
#
class SurvexBlockLookUpManager(models.Manager):
"""Don't know what this does,
https://docs.djangoproject.com/en/dev/topics/db/managers/ """
def lookup(self, name):
if name == "":
blocknames = []
else:
blocknames = name.split(".")
block = SurvexBlock.objects.get(parent=None, survexfile__path=settings.SURVEX_TOPNAME)
for blockname in blocknames:
block = SurvexBlock.objects.get(parent=block, name__iexact=blockname)
return block
# class SurvexBlockLookUpManager(models.Manager):
# """Don't know what this does,
# https://docs.djangoproject.com/en/dev/topics/db/managers/
# This changes the .objects_set thinggy to use a case-insensitive match name__iexact
# so that now SurvexBlock.objects.lookup() works as a case-insensitive match UNUSED
# """
# def lookup(self, name):
# if name == "":
# blocknames = []
# else:
# blocknames = name.split(".")
# # block = SurvexBlock.objects.get(parent=None, survexfile__path=settings.SURVEX_TOPNAME)
# for blockname in blocknames:
# block = SurvexBlock.objects.get(parent=block, name__iexact=blockname)
# return block
class SurvexBlock(models.Model):
@ -120,7 +131,7 @@ class SurvexBlock(models.Model):
Multiple anonymous survex blocks are possible within the same surfex file
"""
objects = SurvexBlockLookUpManager()
# objects = SurvexBlockLookUpManager()
name = models.CharField(max_length=100)
title = models.CharField(max_length=200)
parent = models.ForeignKey("SurvexBlock", blank=True, null=True, on_delete=models.SET_NULL)
@ -163,10 +174,13 @@ class SurvexBlock(models.Model):
class SurvexPersonRole(models.Model):
"""The CASCADE means that if a SurvexBlock or a Person is deleted, then the SurvexPersonRole
is deleted too
"""
survexblock = models.ForeignKey("SurvexBlock", on_delete=models.CASCADE)
# increasing levels of precision, Surely we only need survexblock and person now that we have no link to a logbook entry?
personname = models.CharField(max_length=100)
person = models.ForeignKey("Person", blank=True, null=True, on_delete=models.SET_NULL) # not needed
person = models.ForeignKey("Person", blank=True, null=True, on_delete=models.CASCADE) # not needed
personexpedition = models.ForeignKey("PersonExpedition", blank=True, null=True, on_delete=models.SET_NULL)
def __str__(self):

View File

@ -11,7 +11,7 @@ import settings
"""This file declares TroggleModel which inherits from django.db.models.Model
All TroggleModel and models.Model subclasses inherit persistence in the django relational database. This is known as
the django Object Relational Mapping (ORM).
There are more subclasses define in models_caves.py models_survex.py etc.
There are more subclasses defined in models/caves.py models/survex.py etc.
"""
@ -33,7 +33,7 @@ class TroggleModel(models.Model):
class DataIssue(TroggleModel):
"""When importing cave data any validation problems produce a message which is
recorded as a DataIssue. The django admin system automatically prodiuces a page listing
recorded as a DataIssue. The django admin system automatically produces a page listing
these at /admin/core/dataissue/
This is a use of the NOTIFICATION pattern:
https://martinfowler.com/eaaDev/Notification.html
@ -55,7 +55,6 @@ class DataIssue(TroggleModel):
def __str__(self):
return f"{self.parser} - {self.message}"
#
# single Expedition, usually seen by year
#
@ -150,7 +149,10 @@ class Person(TroggleModel):
class PersonExpedition(TroggleModel):
"""Person's attendance to one Expo"""
"""Person's attendance to one Expo
CASCADE means that if an expedition or a person is deleted, the PersonExpedition
is deleted too
"""
expedition = models.ForeignKey(Expedition, on_delete=models.CASCADE)
person = models.ForeignKey(Person, on_delete=models.CASCADE)

View File

@ -212,6 +212,11 @@ def LoadPositions():
# But why are we doing this? Why do we need the survexblock id for each of these ?
# ..because mostly they don't actually appear in any SVX file. We should match them up
# via the cave data, not by this half-arsed syntactic match which almost never works. PMS.
# It is pointless linking them all to the root survexblock, they don't need it.
# If there is a link to a survexblock it should be the one the station appears in !
# But we are reading the .pos file so we only know the SurvexFile not the SurvexBlock..
# ghastly.
if False:
try:
sbqs = SurvexBlock.objects.filter(survexpath=blockpath)