I have a location model that has one OneToOneField to a city. City has a OneToOneField to state and the State a OneToOneField to a Country.
Country
State
City
are tables in the database that will have populated data I import from data I have using a script. So when the website starts you will be able to select a country a state and a city
The location model has a foreign key to a profile. When I save the profile I have to create the location as well and I cannot create a city again because it already exists in the database and I would get a foreign key constraint violation. So how do I make the value (city_id) I send from the front end match with the city_id in the backend so that value is saved as the city field of the location for a profile? I know I can just save the data as CharFields but then someone can change the name of a city on the front end and then save the wrong value in the database.
Here are my location models:
from django.db import models
from profiles.models import Profile
from django_extensions.db.fields import AutoSlugField
class Country(models.Model):
name = models.CharField(max_length=50)
slug = AutoSlugField(populate_from=["name"])
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
verbose_name = "country"
verbose_name_plural = "countries"
db_table = "countries"
ordering = ["name"]
def __str__(self):
return self.name
def get_absolute_url(self):
return self.slug
class State(models.Model):
name = models.CharField(max_length=50)
slug = AutoSlugField(populate_from=["name"])
country = models.OneToOneField(Country, on_delete=models.CASCADE, default=None)
created_at = models.DateTimeField("date post was created", auto_now_add=True)
updated_at = models.DateTimeField("date post was updated", auto_now=True)
class Meta:
verbose_name = "state"
verbose_name_plural = "states"
db_table = "states"
unique_together = ["country", "name"]
ordering = ["name"]
def __str__(self):
return self.name
def get_absolute_url(self):
return self.slug
class City(models.Model):
name = models.CharField(max_length=50)
slug = AutoSlugField(populate_from=["name"])
state = models.OneToOneField(State, on_delete=models.CASCADE, default=None)
created_at = models.DateTimeField("date post was created", auto_now_add=True)
updated_at = models.DateTimeField("date post was updated", auto_now=True)
class Meta:
verbose_name = "city"
verbose_name_plural = "cities"
db_table = "cities"
unique_together = ["state", "name"]
ordering = ["name"]
def __str__(self):
return self.name
def get_absolute_url(self):
return self.slug
class Location(models.Model):
name = models.CharField(max_length=50, default=None, null=True, blank=True)
street = models.CharField(max_length=100)
additional = models.CharField(max_length=100)
city = models.OneToOneField(City, on_delete=models.CASCADE, related_name="cities")
zip = models.CharField(max_length=30)
phone = models.CharField(max_length=15)
profile = models.ForeignKey(Profile, on_delete=models.CASCADE, null=True, blank=True)
created_at = models.DateTimeField(auto_now_add=True, verbose_name="created at")
updated_at = models.DateTimeField(auto_now=True, verbose_name="updated at")
class Meta:
verbose_name = "location"
verbose_name_plural = "locations"
db_table = "locations"
ordering = ["zip"]
def __str__(self):
return self.name
def get_absolute_url(self):
return self.slug
Also is my approach correct with the way the models are set up or should I do it differently?