Django/Django Rest框架如何允许模型序列化程序将模型的外键字段设置为null?

2024-06-28 20:33:51 发布

您现在位置:Python中文网/ 问答频道 /正文

我希望能够将我的Asset模型中的borrower字段(外键)设置为NULL,但似乎无法使其工作。我试图发送一个带有JSON数据的补丁请求,该数据的键borrower等于NULL值,但是对于模型实例,borrower字段不会更新为NULL。可能是序列化程序有问题,无法将外键字段设置为NULL?在

我已经尝试过将allow_null=True传递给BorrowSerializer类,但没有成功。我在StackOverflow上到处寻找有类似问题和解决方案的帖子,但我所做的一切都没有奏效。在

这是我的模型.py公司名称:

from django.conf import settings
from django.db import models
from django.utils import timezone
from datetime import date
from django.contrib.auth.models import User
from django.urls import reverse

import uuid

class Category(models.Model):
    """Model representing an Asset category"""

    name = models.CharField(max_length=128)

    def __str__(self):
        return self.name

class Borrower(models.Model):
    first_name = models.CharField(max_length=64)
    last_name = models.CharField(max_length=128)
    associated_user = models.ForeignKey(User, on_delete=models.CASCADE, null=True)

    def __str__(self):
        return f'{self.first_name} {self.last_name}'

class Asset(models.Model):
    """Model representing an Asset"""
    # Unique identifier for an instance of an asset (a barcode of sorts)
    uid = models.UUIDField(primary_key=True, default=uuid.uuid4)
    name = models.CharField(max_length=200)
    manufacturer = models.CharField(max_length=64)
    model = models.CharField(max_length=128)
    description = models.TextField()
    category = models.ManyToManyField(Category)
    owner = models.ForeignKey(User, on_delete=models.CASCADE)
    borrower = models.ForeignKey(Borrower, on_delete=models.CASCADE, null=True, blank=True)
    checked_out = models.BooleanField(default=False)
    return_date = models.DateField(null=True, blank=True)    

    CONDITION_TYPE = (
        ('e', 'Excellent'),
        ('g', 'Good'),
        ('f', 'Fair'),
        ('p', 'Poor'),
    )

    condition = models.CharField(
        max_length=1,
        choices=CONDITION_TYPE,
        blank=True,
        help_text='Asset condition')

    class Meta:
            ordering = ['return_date']

    @property
    def is_dueback(self):
        if self.return_date and date.today() > self.return_date:
            return True
        return False

    def display_category(self):
        """Create a string for the Category. This is required to display category in Admin."""
        return ', '.join(category.name for category in self.category.all())

    display_category.short_description = 'Category'

    def __str__(self):
        return f'{self.uid} - {self.name}'

    def get_absolute_url(self):
        return reverse('asset-detail', args=[str(self.uid)])

这是我的序列化程序.py文件:

^{pr2}$

以下是我的DRF API视图:

class AssetRetrieveUpdateDestroy(RetrieveUpdateDestroyAPIView):
    lookup_field = 'uid'
    serializer_class = AssetSerializer

    def get_queryset(self):
        user = self.request.user
        return Asset.objects.filter(owner=user)

class BorrowerRetrieveUpdateDestroy(RetrieveUpdateDestroyAPIView):
    lookup_field = 'id'
    serializer_class = BorrowerSerializer

    def get_queryset(self):
        return Borrower.objects.all()

我希望当我传入这个JSON时,Asset模型实例中的borrower字段将更新为NULL:

data = {
   'borrower': null
}

但是,当borrower字段是外键时,我的模型实例不会更新它。如果字段是CharField或其他类型,但在外键上,则可以正常工作。我打印了AJAX请求返回的数据,但是borrower字段保持不变。在

提前感谢您能提供的任何帮助。在


Tags: namefromimportselftruereturnmodelsdef
1条回答
网友
1楼 · 发布于 2024-06-28 20:33:51

来自the docs

If you're supporting writable nested representations you'll need to write .create() or .update() methods that handle saving multiple objects.

因此,您需要在AssetSerializer中实现.update()方法:

class AssetSerializer(serializers.ModelSerializer):
    borrower = BorrowerSerializer(allow_null=True)
    ...

    class Meta:
        model = Asset
        fields = (...)

    def update(self, instance, validated_data):
        instance.borrower = validated_data.get('borrower')
        instance.save()

        return instance

这应该能起作用。因此,无论您传递了allow_null=True,它都将接受null值,但不会更新嵌套关系,除非您定义了自定义更新机制。在

相关问题 更多 >