Skip to main content
 首页 » 编程设计

python之Django REST Framework 序列化程序之访问现有的外键

2024年08月19日32telwanggs

我正在使用 Django Rest Framework在我的应用程序中,我需要创建包含外键的新模型实例。这些引用另一个表中的现有对象,因此我不希望创建这些外来对象的新实例。此外,我无法通过主键访问这些对象,因为未提交该信息(我需要过滤 包含在 POST 请求中的某些字段)。

我该怎么做? This问题似乎解决了同样的问题,但我不清楚接受的答案是否真的解决了问题。假设我有两个模型,Category 和 Item,后者的 ForeignKey 字段指定类别:

class Category(models.Model): 
    name = models.TextField() 
    format = models.TextField() 
    page = models.IntegerField(default=1) 
    order = models.IntegerField(default=1) 
 
class Item(models.Model): 
    username = models.TextField() 
    title = models.TextField() 
    category = models.ForeignKey('Category', null=True) 
    data = JSONField(null=True, blank=True) 

POST 请求的主体由一个 JSON 负载组成,类别定义为指定格式、页面和订单字段的对象:

POST /api/items 
{ 
  "username" : "test", 
  "title" : "foo", 
  "category" : { 
    "format" : "A", 
    "page" : 2, 
    "order" : 1 
  }, 
  "data" : [1,2,3,4,5] 
} 

然后我想我可以如下定义我的 Item 序列化器,覆盖 create 以便它通过过滤检索正确的 Category 实例适当的字段,并将其设置到返回的 Item 实例中:

class ItemSerializer(serializers.ModelSerializer): 
    category = CategorySerializer() 
    data = serializers.ListField() 
 
    class Meta: 
        model = Item 
        fields = ('username', 'title', 'category', 'data') 
 
    def create(self, validated_data): 
        category_dict = validated_data.pop('category') 
        item = Item.objects.create(**validated_data) 
        format = category_dict.format 
        page = category_dict.page 
        order = category_dict.order 
        item.category = Category.objects.get(format=format, page=page, order=order) 
        return item 

这是正确的做法吗?

请您参考如下方法:

会像

try: 
    category = Category.objects.get(format=format, page=page, order=order) 
except Category.DoesNotExist: 
    # either make it None or create new category, depends on your requirement 
    category = None 
    # or create new category 
except Category.MultipleObjectsReturned: 
    category = category.first() # it depends on your requirement 
item.category = category