I'm trying to populate the data in the database for the Employee
Model
Also, I'm not going to use Foreign Key ID's as given below
Example 1:
- model: employee.employee
pk: 1
fields:
user: 1
manager: NULL
department: 1
job_level: 5
created_at: '2021-06-03'
updated_at: '2021-06-03'
Instead, I'm going to Use Unique values of the respective Model as given below
Example 2:
- model: employee.employee
pk: 1
fields:
user: [manager.finance]
manager: NULL
department: [Finance]
job_level: [MNGR]
created_at: '2021-06-03'
updated_at: '2021-06-03'
models.py File
from django.db import models
from django.conf import settings
from django.db.models import Q
class TimestampedModel(models.Model):
created_at = models.DateField(auto_now_add=True)
updated_at = models.DateField(auto_now=True)
class Meta:
abstract = True
class DepartmentManager(models.Manager):
def get_by_natural_key(self, name):
return self.get(name=name)
class Department(TimestampedModel):
name = models.CharField(max_length=128, unique=True)
objects = DepartmentManager()
class Meta:
db_table = 'tc_departments'
def __str__(self):
return f'{self.name}'
class JobLevelManager(models.Manager):
def get_by_natural_key(self, handle):
return self.get(handle=handle)
class JobLevel(models.Model):
handle = models.CharField(max_length=32, unique=True)
display_name = models.CharField(max_length=64, null=True, blank=True)
objects = JobLevelManager()
class Meta:
db_table = 'tc_job_levels'
def __str__(self):
return f'{self.handle} and {self.display_name}'
class EmployeeManager(models.Manager):
def get_by_natural_key(self, user):
return self.get(user=user)
class Employee(TimestampedModel):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.PROTECT)
manager = models.ForeignKey('self', on_delete=models.CASCADE,
limit_choices_to={'manager__isnull': True}, null=True, blank=True)
department = models.ForeignKey(Department, on_delete=models.CASCADE)
job_level = models.ForeignKey(JobLevel, on_delete=models.CASCADE)
profile_pic = models.ImageField(upload_to='photos/%Y/%m/%d', max_length=128,
null=True,
blank=True)
objects = EmployeeManager()
class Meta:
db_table = 'tc_employees'
unique_together = [['department', 'job_level']]
def __str__(self):
return f'{self.user}'
class Asset(TimestampedModel):
class DeviceType(models.TextChoices):
PHONE = 'PH', 'Phone'
TABLET = 'TB', 'Tablet'
LAPTOP = 'LP', 'Laptop'
DESKTOP = 'DS', 'Desktop'
device_type = models.CharField(max_length=2,
choices=DeviceType.choices,
default=DeviceType.LAPTOP)
serial_number = models.CharField(max_length=32, unique=True)
assigned_to = models.ForeignKey(Employee, on_delete=models.PROTECT)
assigned_on = models.DateTimeField()
returned_on = models.DateTimeField(blank=True, null=True)
class Meta:
db_table = 'tc_assets'
def __str__(self):
return f'{self.device_type.label} serial: {self.serial_number}'
Let's consider Example 2 I'm going to populate data as like in Example 2 To do that
We can use the user
field from Employee
Model because the user
field is unique
If I use the below YAML file I'm getting an error
Example 3:
- model: employee.employee
pk: 1
fields:
user: [manager.finance]
manager: NULL
department: [Finance]
job_level: [MNGR]
created_at: '2021-06-03'
updated_at: '2021-06-03'
- model: employee.employee
pk: 2
fields:
user: [team_leader.finance]
manager: [manager.finance]
department: [Finance]
job_level: [LEAD]
created_at: '2021-06-03'
updated_at: '2021-06-03'
Error
Traceback (most recent call last):
File "/home/selvaganesh/.virtualenvs/mtest/lib/python3.8/site-packages/django/db/models/fields/__init__.py", line 1823, in get_prep_value
return int(value)
ValueError: invalid literal for int() with base 10: 'manager.finance'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/selvaganesh/.virtualenvs/mtest/lib/python3.8/site-packages/django/core/serializers/python.py", line 134, in Deserializer
value = base.deserialize_fk_value(field, field_value, using, handle_forward_references)
File "/home/selvaganesh/.virtualenvs/mtest/lib/python3.8/site-packages/django/core/serializers/base.py", line 310, in deserialize_fk_value
obj = default_manager.db_manager(using).get_by_natural_key(*field_value)
File "/home/selvaganesh/models/mtest/employee/models.py", line 67, in get_by_natural_key
return self.get(user=user)
File "/home/selvaganesh/.virtualenvs/mtest/lib/python3.8/site-packages/django/db/models/manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/home/selvaganesh/.virtualenvs/mtest/lib/python3.8/site-packages/django/db/models/query.py", line 424, in get
clone = self._chain() if self.query.combinator else self.filter(*args, **kwargs)
File "/home/selvaganesh/.virtualenvs/mtest/lib/python3.8/site-packages/django/db/models/query.py", line 941, in filter
return self._filter_or_exclude(False, args, kwargs)
File "/home/selvaganesh/.virtualenvs/mtest/lib/python3.8/site-packages/django/db/models/query.py", line 961, in _filter_or_exclude
clone._filter_or_exclude_inplace(negate, args, kwargs)
File "/home/selvaganesh/.virtualenvs/mtest/lib/python3.8/site-packages/django/db/models/query.py", line 968, in _filter_or_exclude_inplace
self._query.add_q(Q(*args, **kwargs))
File "/home/selvaganesh/.virtualenvs/mtest/lib/python3.8/site-packages/django/db/models/sql/query.py", line 1391, in add_q
clause, _ = self._add_q(q_object, self.used_aliases)
File "/home/selvaganesh/.virtualenvs/mtest/lib/python3.8/site-packages/django/db/models/sql/query.py", line 1410, in _add_q
child_clause, needed_inner = self.build_filter(
File "/home/selvaganesh/.virtualenvs/mtest/lib/python3.8/site-packages/django/db/models/sql/query.py", line 1345, in build_filter
condition = self.build_lookup(lookups, col, value)
File "/home/selvaganesh/.virtualenvs/mtest/lib/python3.8/site-packages/django/db/models/sql/query.py", line 1191, in build_lookup
lookup = lookup_class(lhs, rhs)
File "/home/selvaganesh/.virtualenvs/mtest/lib/python3.8/site-packages/django/db/models/lookups.py", line 25, in __init__
self.rhs = self.get_prep_lookup()
File "/home/selvaganesh/.virtualenvs/mtest/lib/python3.8/site-packages/django/db/models/fields/related_lookups.py", line 117, in get_prep_lookup
self.rhs = target_field.get_prep_value(self.rhs)
File "/home/selvaganesh/.virtualenvs/mtest/lib/python3.8/site-packages/django/db/models/fields/__init__.py", line 1825, in get_prep_value
raise e.__class__(
ValueError: Field 'id' expected a number but got 'manager.finance'.
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "manage.py", line 22, in <module>
main()
File "manage.py", line 18, in main
execute_from_command_line(sys.argv)
File "/home/selvaganesh/.virtualenvs/mtest/lib/python3.8/site-packages/django/core/management/__init__.py", line 419, in execute_from_command_line
utility.execute()
File "/home/selvaganesh/.virtualenvs/mtest/lib/python3.8/site-packages/django/core/management/__init__.py", line 413, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/home/selvaganesh/.virtualenvs/mtest/lib/python3.8/site-packages/django/core/management/base.py", line 354, in run_from_argv
self.execute(*args, **cmd_options)
File "/home/selvaganesh/.virtualenvs/mtest/lib/python3.8/site-packages/django/core/management/base.py", line 398, in execute
output = self.handle(*args, **options)
File "/home/selvaganesh/.virtualenvs/mtest/lib/python3.8/site-packages/django/core/management/commands/loaddata.py", line 78, in handle
self.loaddata(fixture_labels)
File "/home/selvaganesh/.virtualenvs/mtest/lib/python3.8/site-packages/django/core/management/commands/loaddata.py", line 123, in loaddata
self.load_label(fixture_label)
File "/home/selvaganesh/.virtualenvs/mtest/lib/python3.8/site-packages/django/core/management/commands/loaddata.py", line 181, in load_label
for obj in objects:
File "/home/selvaganesh/.virtualenvs/mtest/lib/python3.8/site-packages/django/core/serializers/pyyaml.py", line 76, in Deserializer
yield from PythonDeserializer(yaml.load(stream, Loader=SafeLoader), **options)
File "/home/selvaganesh/.virtualenvs/mtest/lib/python3.8/site-packages/django/core/serializers/python.py", line 136, in Deserializer
raise base.DeserializationError.WithData(e, d['model'], d.get('pk'), field_value)
django.core.serializers.base.DeserializationError: Problem installing fixture '/home/selvaganesh/models/mtest/employee/fixtures/employee.yaml': Field 'id' expected a number but got 'manager.finance'.: (employee.employee:pk=2) field_value was '['manager.finance']'
The problem I'm facing is only because of the pk: 2
, manager
field in Example 3
Example 2 is working Fine
Other Foreign Key Fields user
, department
, job_level
everything working fine
If I use manager: NULL
working fine But If I use manager: [manager.fianance]
I'm getting an Error
How to resolve this Problem manager: [manager.finance]
Please help me out