Django 中 save_model 函数中 related_name 的连接问题

问题描述 投票:0回答:1

有一个模型叫

Borrow
。在
BorrowLine
模型中,ForeignKey 是用 related_name
lines
定义的。我为
BorrowAdmin
模型写下
BorrowLineInline
Borrow
。在
BorrowAdmin
类中,我使用了
save_model
函数,如下所示:

def save_model(self, request, obj, form, change):
    obj.save()
    print(obj.lines)
    return super(BorrowAdmin, self).save_model(request, obj, form, change)

但是当我在 Django 管理中添加

Borrow
模型的实例时,控制台中会打印以下行:
borrow.BorrowLine.None
我无法访问任何
BorrowLine
字段。例如,它的字段之一是 book,但是当我调用它时,它给出了以下错误:
'RelatedManager' object has no attribute 'book'
我该如何解决这个问题并访问类字段?

我的代码:

class Borrow(models.Model):
    student = models.ForeignKey('student.Student', on_delete=models.CASCADE, related_name='borrow')
    created_time = models.DateField(auto_now_add=True)
    delivery_time = models.DateField(default=date.today() + timedelta(days=7), validators=[delivery_time_validator])
    delivered = models.BooleanField(default=False)

    def __str__(self):
        return str(self.student)


class BorrowLine(models.Model):
    borrow = models.ForeignKey('Borrow', on_delete=models.CASCADE, related_name='lines')
    book = models.ForeignKey('book.Book', on_delete=models.CASCADE, related_name='lines')

    def __str__(self):
        return f'{self.borrow} -> {self.book}'

    def clean(self):
        book = self.book
        if not book.is_available:
            raise ValidationError(f'The book {book.title} is not available.')
class BorrowLineInline(admin.TabularInline):
    model = BorrowLine
    extra = 1
    max_num = 3
    autocomplete_fields = ('book',)


@admin.register(Borrow)
class BorrowAdmin(admin.ModelAdmin):
    inlines = (BorrowLineInline,)
    list_display = ('student', 'created_time', 'delivery_time', 'delivered')
    search_fields = ('student__first_name', 'student__last_name', 'lines__book__title')
    list_filter = ('student__class_type', 'delivered', 'created_time', 'delivery_time')
    autocomplete_fields = ('student',)

    def add_view(self, request, form_url="", extra_context=None):
        self.fields = ('student', 'delivery_time')
        return super(BorrowAdmin, self).add_view(request, form_url=form_url, extra_context=extra_context)

    def change_view(self, request, object_id, form_url="", extra_context=None):
        self.fields = ('student', 'delivery_time', 'delivered')
        return super(BorrowAdmin, self).change_view(request, object_id, form_url=form_url, extra_context=extra_context)

    def save_model(self, request, obj, form, change):
        obj.save()
        print(obj.lines.book)
        # Do something
        return super(BorrowAdmin, self).save_model(request, obj, form, change)

我还使用了

post_save
pre_save
等信号来代替
save_model
,但它们也有同样的错误并返回 None。

django django-models django-admin signals
1个回答
0
投票

经理总是打印

app_name.ModelName.None
,你需要与
QuerySet
一起工作,所以:

def save_model(self, request, obj, form, change):
    obj.save()
    print(obj.lines.all())
    return super().save_model(request, obj, form, change)

话虽如此,它不会显示lines

,因为它会首先保存
obj
,然后保存它的多对多关系。因此,您可以在保存整个模型之后检查关系:
def save_model(self, request, obj, form, change): return super().save_model(request, obj, form, change) print(obj.lines.all())


注意
:自

PEP-3135 [pep] 起,如果第一个参数是定义方法的类,第二个参数是方法,则无需带参数调用 super(…)函数的第一个参数(通常为 self

)。
    

© www.soinside.com 2019 - 2024. All rights reserved.