mysqldjangodatabasedjango-modelscomposite-primary-key

Django mySQL database insert query using .save() and .validate_unique with a composite primary key


I am trying to insert directly into a mySQL database table that has a composite primary key value consisting of 'Fname', 'Lname' and 'DOB'. I want to allow the user to be able to add to the database directly from the web application though using a request.POST form method in Django and getting the user input to insert into the database if it does not violate a duplicate primary key value. However, Django only allows you to assign one primary key value to a model field.

This is the table model Athlete_T that also has a Meta class with a unique_together field specifying the composite primary key.

class AthleteT(models.Model):
fname = models.CharField(db_column='Fname', primary_key=True, max_length=30)  # Field name made lowercase.
lname = models.CharField(db_column='Lname', max_length=30)  # Field name made lowercase.
dob = models.CharField(db_column='DOB', max_length=10)  # Field name made lowercase.
sportsteam = models.CharField(db_column='SportsTeam', max_length=30, blank=True, null=True)  # Field name made lowercase.
position = models.CharField(db_column='Position', max_length=30, blank=True, null=True)  # Field name made lowercase.
year = models.CharField(db_column='Year', max_length=15, blank=True, null=True)  # Field name made lowercase.
height = models.FloatField(db_column='Height', blank=True, null=True)  # Field name made lowercase.
#upload_to='staticfiles/images'
image = models.TextField(db_column='Image', blank=True, null=True)  # Field name made lowercase.

class Meta:
    managed = False
    db_table = 'Athlete_T'
    unique_together = (('fname', 'lname', 'dob'),)

Next is my views.py where I created a page that takes the user input and queries a model.validate_unique() and model.save() function which should this not insert the new value into the database?

def AddAthlete(request):

if request.method == 'POST':
    newFname = request.POST['fname']
    newLname = request.POST['lname']
    newYear = request.POST['year']
    newHeight = request.POST['height']
    newImage = request.POST['image']
    newDOB = request.POST['dob']
    newTeam = request.POST['sportsteam']
    newPosition = request.POST['position']

    newAthlete = AthleteT(fname=newFname, lname=newLname, dob=newDOB, sportsteam=newTeam, position=newPosition, year=newYear, height=newHeight, image=newImage)

    newAthlete.validate_unique()
    newAthlete.save()

According to Django Documentation, validate_unique should be checking the Meta.unique_together on the model. However, if I try to insert two values with the same 'Fname' only then I get a duplicate primary key error. Any thoughts on how to fix this? I have also tried making a separate form class and using the form.is_valid() technique and I am still presented with the same problem.


Solution

  • I found out that it is simply not possible to have a composite primry key in Django...

    You can use constraints to limit and guide the user input but django wants you to make use of a unique primary key id field that gets auto generated when you do not specify a primary key = true parameter in an attribute to one of your models.

    class AthleteT(models.Model):
    id = models.BigAutoField(primary_key=True)