Reputation: 71
First of all pardon me for my poor English. I'm using django-import-export to upload excel file into my student model that has foreign key relationship with university model
student.. models.py
:
class Student(models.Model):
institution = models.ForeignKey(University, on_delete=models.CASCADE)
id = models.CharField(max_length=200, primary_key=True)
first_name = models.CharField(max_length=200)
middle_name = models.CharField(max_length=200)
last_name = models.CharField(max_length=200)
age = models.IntegerField()
faculty = models.CharField( max_length=200, null=True, blank=True)
program = models.CharField( max_length=200, null=True, blank=True)
def __str__(self):
return self.first_name
university.. models.py
:
class University(models.Model):
name = models.CharField(max_length=300)
email = models.EmailField(max_length=255, unique=True)
phone_no1 = PhoneNumberField()
phone_no2 = PhoneNumberField(blank=True)
fax_no = PhoneNumberField()
website = models.URLField(max_length=200)
pob = models.IntegerField()
city = models.CharField(max_length=200, blank=True)
logo = models.ImageField(upload_to="logos/", blank=True, null=True)
def __str__(self):
return self.name
After reading django-import-export documentation about ForeignKeyWidget I edited my resources.py file as following and it works fine when I upload excel file that contain institution id and other student information
resources.py
class StudentResource(resources.ModelResource):
institution = fields.Field(
column_name='institution',
attribute ='institution',
widget = ForeignKeyWidget(University, 'id')
)
class Meta:
model=Student
But I don't want to include institution id into my excel file while I am uploading, because I can find the institution id from Registrar Staff logged in since the RegistrarStaff model has foreign key relationship with university model
class RegistrarStaff(models.Model):
user = models.OneToOneField(User, on_delete = models.CASCADE, primary_key = True)
university = models.ForeignKey(University, on_delete=models.CASCADE, null=True)
phone_number = models.CharField(max_length=20)
def __str__(self):
return str(self.user)
This is the way I able to find institution id based on whose university Registrar Staff is logged in and passed the value into resource like on number 4 in views.py
views.py
:
def upload(request):
if request.method == 'POST':
loged=request.user.id
univ = RegistrarStaff.objects.get(pk=loged).university_id
student_resource = StudentResource(institution=univ)
dataset = Dataset()
new_student = request.FILES['myfile']
if not new_student.name.endswith('xlsx'):
messages.info(request,'Wrong format')
return render(request, 'upload.html')
imported_data = dataset.load(new_student.read(), format='xlsx')
for data in imported_data:
value = Student(
data[0],
data[1],
data[2],
data[3],
data[4],
data[5],
)
value.save()
return render(request, 'upload.html')
And I intialized it in resources.py as follow
resources.py
:
class StudentResource(resources.ModelResource):
def __init__(self, *args, **kwargs):
self._institution=kwargs.pop('institution', None)
super().__init__(*args, **kwargs)
print(self._institution)
class Meta:
model=Student
So, is there anyway I can set the value of institution id = self._institution so as to able to upload excel file that doesn't contain institution id????
Upvotes: 2
Views: 2211
Reputation: 4231
You are on the right lines. The way to do this is to pass the institution instance (or id) into the constructor, which is what you have already. All you need to do is to set the institution
instance onto the Student model instance before it is saved:
class StudentResource(resources.ModelResource):
def __init__(self, *args, **kwargs):
self._institution=kwargs.pop('institution', None)
super().__init__(*args, **kwargs)
print(self._institution)
def before_save_instance(self, instance, using_transactions, dry_run):
setattr(instance, "institution", self._institution)
class Meta:
model=Student
However, you are bypassing the django-import-export
framework by calling Student.save()
directly. Don't do this. Use the framework to handle instance creation for you (docs):
result = student_resource.import_data(imported_data, dry_run=True)
Upvotes: 2