簡體   English   中英

管理員中通過CSV批量導入Django完整性錯誤

[英]Django Integrity Error in Bulk Import via CSV in Admin

我正在嘗試在Django Admin中實現CSV導入並保存與CSV文件行對應的批量數據。 我有一個帶有OneToOneField的模型Employee到Django的Auth模型。 我寫了一個接受csv文件的自定義表單。 但是,當我調用super()。save()方法時,我得到了一個完整性錯誤。

我的Model類是:

class Employee(models.Model):
    user = models.OneToOneField(User, primary_key=True)
    company = models.ForeignKey(Companies)
    department = models.ForeignKey(Departments)
    mobile = models.CharField(max_length=16, default="0", blank=True)
    gender = models.CharField(max_length=1, default="m", choices=GENDERS)
    image = models.ImageField(upload_to=getImageUploadPath, null=True, blank=True)
    designation = models.CharField(max_length=64)
    is_hod = models.BooleanField(default=False)
    is_director = models.BooleanField(default=False)

這是我的Admin類:

class EmployeeAdmin(admin.ModelAdmin):
    list_display = ('user', 'company', 'department', 'designation', 'is_hod', 'is_director')
    search_fields = ['user__email', 'user__first_name', 'user__last_name']
    form = EmployeeForm

這是我的Form類:

class EmployeeForm(forms.ModelForm):
    company = forms.ModelChoiceField(queryset=Companies.objects.all())
    file_to_import = forms.FileField()

    class Meta:
        model = Employee
        fields = ("company", "file_to_import")

    def save(self, commit=True, *args, **kwargs):
        try:
            company = self.cleaned_data['company']
            records = csv.reader(self.cleaned_data['file_to_import'])
            for line in records:
                # Get CSV Data.

                # Create new employee.
                employee = CreateEmployee(email, firstName, lastName, gender, '', company.id, dept[0].id, designation, 
                           isSuperuser, isHod, isDirector)
            super(EmployeeForm, self).save(*args, **kwargs)

        except Exception as e:
            traceback.print_exc()
            raise forms.ValidationError('Something went wrong.')

CreateEmployee方法定義為:

@transaction.atomic
def CreateEmployee(email='', firstName='', lastName='', gender='', mobile='',
    companyId='', departmentId='', designation='', isSuperuser=False, isHod=False, isDirector=False):
    try:
        user = User(
            username=email,
            email=email,
            first_name=firstName,
            last_name=lastName,
            is_superuser=isSuperuser,
            is_active=True)
        password = getPassword(firstName, lastName)
        user.set_password(password)
        user.save()

        company = Companies(id=companyId)
        dept = Departments(id=departmentId)

        employee = Employee(
            user=user,
            mobile=mobile,
            gender=gender,
            designation=designation,
            company=company,
            department=dept,
            is_hod=isHod,
            is_director=isDirector)
        employee.save()
        return employee
    except DatabaseError as e:
        raise e
    return None

我在表單的例外情況下得到一個異常,其中包含錯誤: IntegrityError: (1048, "Column 'user_id' cannot be null")

在回溯中,我可以看到異常是在super(EmployeeForm, self).save(*args, **kwargs)行中引發的。 我假設super方法正在嘗試保存實例。

完整的追溯是:

Traceback (most recent call last):
  File "/home/rachit/Projects/project/users/forms.py", line 81, in save
    super(EmployeeForm, self).save(*args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/django/forms/models.py", line 455, in save
    construct=False)
  -- lot of text --
IntegrityError: (1048, "Column 'user_id' cannot be null")

我猜測ModelForm的save方法正在嘗試保存實例,但我不希望這種情況發生,因為我創建了多個用戶。

我在這做錯了什么? 有沒有其他方法來實現我想要的?

TIA。

由於您正在進行自己的保存,因此無需在超級表單上調用save。 通常,當您需要像這樣填寫外鍵字段時,使用commit = False來獲取未保存模型的實例。但您可以執行以下任一操作:

def save(self, commit=True, *args, **kwargs):
    try:
        company = self.cleaned_data['company']
        records = csv.reader(self.cleaned_data['file_to_import'])
        for line in records:
            # Get CSV Data.

            # Create new employee.
            employee = CreateEmployee(email, firstName, lastName, gender, '', company.id, dept[0].id, designation, 
                       isSuperuser, isHod, isDirector)
        # super(EmployeeForm, self).save(*args, **kwargs)
        # - or -
        super(EmployeeForm, self).save(commit=False)
        # updated based on additional comment
        return employee

    except Exception as e:
        traceback.print_exc()
        raise forms.ValidationError('Something went wrong.')

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM