Django cannot query data from another table by using OneToOneField
Question:
I create django model like this which api_key of Setting table is OneToOneField to Key table.
class Key(models.Model):
api_key=models.CharField(max_length=100,unique=True)
api_key_name=models.CharField(max_length=100)
def __str__(self):
return self.api_key
class Setting(models.Model):
api_key=models.OneToOneField(Key,on_delete=models.CASCADE)
field_en=models.BooleanField(default=False)
def __str__(self):
return str(self.api_key)
I add data to table Key like this.
api_key="abc1"
api_key_name="test"
In views.py I use key to query like this code.
def keyForm(request):
key="abc1"
data, created = Setting.objects.get_or_create(api_key__api_key=key)
key = Key.objects.get(api_key=key)
data = {'setting':data, 'key':key}
return render(request,'key_form.html', data)
Data in table Key
It show error like this. How to fix it?
MySQLdb._exceptions.OperationalError: (1048, "Column 'api_key_id' cannot be null")
IntegrityError at /keyForm
(1048, "Column 'api_key_id' cannot be null")
Answers:
Change data, created = Setting.objects.get_or_create(api_key__api_key=key)
to data, created = Setting.objects.get_or_create(api_key_id=key)
. Should work.
But it would be better if you validate key as well:
from django.shortcuts import get_object_or_404
def key_form(request):
key="abc1"
key_instance = get_object_or_404(Key, api_key=key)
data, created = Setting.objects.get_or_create(api_key=key_instance)
key = Key.objects.get(api_key=key)
data = {'setting':data, 'key':key}
return render(request,'key_form.html', data)
- You are linking Settings to DeviceKey, and not to Key
class Setting(models.Model):
api_key=models.OneToOneField(DeviceKey,on_delete=models.CASCADE)
field_en=models.BooleanField(default=False)
def __str__(self):
return str(self.api_key)
- You are getting the error in key_form view, because
when you create a Settings object you are providing key value as a parameter, and in Django it doesn’t work this way. You need to provide a valid key instance, as a parameter.
The code provided by Zorking explains how you can do this.
I create django model like this which api_key of Setting table is OneToOneField to Key table.
class Key(models.Model):
api_key=models.CharField(max_length=100,unique=True)
api_key_name=models.CharField(max_length=100)
def __str__(self):
return self.api_key
class Setting(models.Model):
api_key=models.OneToOneField(Key,on_delete=models.CASCADE)
field_en=models.BooleanField(default=False)
def __str__(self):
return str(self.api_key)
I add data to table Key like this.
api_key="abc1"
api_key_name="test"
In views.py I use key to query like this code.
def keyForm(request):
key="abc1"
data, created = Setting.objects.get_or_create(api_key__api_key=key)
key = Key.objects.get(api_key=key)
data = {'setting':data, 'key':key}
return render(request,'key_form.html', data)
Data in table Key
It show error like this. How to fix it?
MySQLdb._exceptions.OperationalError: (1048, "Column 'api_key_id' cannot be null")
IntegrityError at /keyForm
(1048, "Column 'api_key_id' cannot be null")
Change data, created = Setting.objects.get_or_create(api_key__api_key=key)
to data, created = Setting.objects.get_or_create(api_key_id=key)
. Should work.
But it would be better if you validate key as well:
from django.shortcuts import get_object_or_404
def key_form(request):
key="abc1"
key_instance = get_object_or_404(Key, api_key=key)
data, created = Setting.objects.get_or_create(api_key=key_instance)
key = Key.objects.get(api_key=key)
data = {'setting':data, 'key':key}
return render(request,'key_form.html', data)
- You are linking Settings to DeviceKey, and not to Key
class Setting(models.Model):
api_key=models.OneToOneField(DeviceKey,on_delete=models.CASCADE)
field_en=models.BooleanField(default=False)
def __str__(self):
return str(self.api_key)
- You are getting the error in key_form view, because
when you create a Settings object you are providing key value as a parameter, and in Django it doesn’t work this way. You need to provide a valid key instance, as a parameter.
The code provided by Zorking explains how you can do this.