Django -更新数据库条目(如果存在)或插入新条目,将两个表组合在一起(模型)

qlfbtfca  于 12个月前  发布在  Go
关注(0)|答案(1)|浏览(138)

我有一个应用程序,将两个Excel文件合并为一个(来自学生的数据和来自其科目成绩的数据)。因此,一个表用于学生,一个表用于成绩。下面是我的models.py的外观:

models.py

class Students(models.Model):
    study_program = models.CharField(max_length=40, blank=True, null=True)
    registration_number = models.IntegerField(blank=True, null=True)
    id_number_1 = models.FloatField(blank=True, null=True)
    name = models.CharField(max_length=100, null=True)
    surname = models.CharField(max_length=100)
    nationality = models.CharField(max_length=10)
    .
    .
    (many more columns here)
    .
    def __str__(self):
        return self.name + ' ' + self.surname

class StudentGrades(models.Model):
    student = models.ForeignKey(Students, default=None, on_delete=models.CASCADE)
    subject = models.CharField(max_length=40)  # Μάθημα (Subject)
    subject_code = models.CharField(max_length=20, )  # Κωδ. μαθ. (Subject Code)
    student_class = models.CharField(max_length=40, )  # Τμήμα Τάξης (Class)
    .
    .
    (many more columns here)
    .
    def __str__(self):
        return self.subject + ' ' + self.student.name + ' ' + self.student.surname

字符串
连接这两个的主键是学生的注册号。每个学生都有一个唯一的注册号。在views.py上,我创建了两个函数(每个表一个),将Excel文件的内容保存到数据库。下面是views.py:

views.py

此函数将 students 记录保存到数据库中。如果学生的行具有匹配的注册号,则更新记录,否则将其作为新记录插入。

def update_or_create_student(df):
    try:
        df = df[0]
    except:
        return redirect('/dashboard/upload/students')

    for i in range(len(df)):
        AM = df.iloc[i]['ΑΜ']
        if Students.objects.filter(registration_number=AM).exists():
            print('updated..')
            Students.objects.filter(registration_number=AM).update(
                study_program=df.iloc[i]['ΠΣ'],
                registration_number=df.iloc[i]['ΑΜ'],
                id_number_1=df.iloc[i]['Ακ. Ταυτότητα'],
                name=df.iloc[i]['Όνομα'],
                surname=df.iloc[i]['Επώνυμο'],
                .
                .
                .
            )
        else:
            print('created..')
            Students(
                study_program=df.iloc[i]['ΠΣ'],
                registration_number=df.iloc[i]['ΑΜ'],
                .
                .
                .
            ).save()


这个函数现在对学生的成绩做同样的事情。

def updated_or_create_grades(df):
    try:
        df = df[0]
    except:
        return redirect('/dashboard/upload/grades')

    student_id = None
    for i in range(len(df)):
        reg_no = df.iloc[i]["AM"]
        if Students.objects.filter(registration_number=reg_no).exists():
            student_id = Students.objects.get(registration_number=reg_no)

        if StudentGrades.objects.filter(registration_number=df.iloc[i]["AM"]).exists():
            print('updated..')
            StudentGrades.objects.filter(student=student_id).update(
                subject_code=df.iloc[i]['Κωδ. μαθ.'],
                subject_of_academic_year=df.iloc[i]['Μάθημα Ακ. Έτους'],
                student_class=df.iloc[i]['Τμήμα Τάξης'],
                .
                .
                .
        else:
            print('created..')
            StudentGrades(
                student=student_id,
                subject_code=df.iloc[i]['Κωδ. μαθ.'],
                subject_of_academic_year=df.iloc[i]['Μάθημα Ακ. Έτους'],
                student_class=df.iloc[i]['Τμήμα Τάξης'],
                .
                .
                .
            ).save()


这里是问题.这只适用于当关系是1:1(一个学生有一个科目/年级).这是应用程序的原始功能.然而,我想扩大这一点,包括许多科目/年级(因此1:N,每个学生都参加了多个科目).没有必要创建第三个模型/表,因为每个新的等级Excel文件具有完全相同的列格式.
我想修改代码,以包括学生参加的所有科目的所有成绩的记录。每个科目都有一个代码,所以我想通过注册号和科目代码进行过滤,但我无法在我的函数中实现它。我认为没有必要在第一个函数中做任何修改,只有在updated_or_create_grades函数中。如果有任何帮助,这是表中主题代码的列:

subject_code = models.CharField(max_length=20, )


如果我尝试按原样插入它,它只会保留学生的最新记录,因为它会检查他的注册号并更新它,因此会丢失上一个科目/年级的记录。例如,如果我上传10个不同的Excel文件(10个不同的年级),而学生已经参加了所有10个,数据库只会保留最新的科目记录,并丢弃其余的。

xdyibdwo

xdyibdwo1#

我认为你的代码是限制DF只有第一个元素。输入DF可能有所有的成绩信息,但你是切片和提取只有第一个元素?

df = df[0]

字符串

相关问题