只复制非关系属性django/python

tpxzln5u  于 2022-11-27  发布在  Python
关注(0)|答案(3)|浏览(145)

我正在将一个模型对象复制到另一个模型对象,但不希望复制关系
例如,假设您有一个如下所示的模型:

class Dish(models.Model):
    name = models.CharField(max_length=100)
    description = models.CharField(max_length=500)
    category = models.ForeignKey(Category, on_delete=models.CASCADE, default=1)

    def __str__(self):
        return self.name

然后我做:

my_dish = Dish.objects.get(pk=dish.id)
            serializer = Dish_Serializer(my_dish)
            my_new_object = serializer.data

我希望my_new_object只包含那些不是关系的属性,在本例中是name和description。
如何在不直接访问名称和描述的情况下执行此操作?

igetnqfo

igetnqfo1#

我假设你不想在序列化器中显式定义要序列化的字段,否则你可以做以下操作:

class Dish_Serializer(serializers.ModelSerializer):
    class Meta:
        model = Dish
        fields = ['id','name', 'description']

您可以动态定义这些字段:

fields = [f.name for f in Dish._meta.concrete_fields]

fields = [f.name for f in Dish._meta.fields if not isinstance(f,ForeignKey)]
f87krz0w

f87krz0w2#

最后,你希望my_new_object是字典格式,并且根据条件pk只会给予你一个dish对象。所以,你可以这样做:

my_new_object = Dish.objects.filter(pk=dish.id).values("name", "description")[0]

它会给予你确切的你想要的,只要声明你需要的字段在值作为一个属性字段。

ohfgkhjo

ohfgkhjo3#

您可以使用.fields.pop(field_name)方法从您的 * 序列化程序 * 中删除 * 字段 ,如下面的示例所示。根据我从*Dynamically modifying fields**[drf-docs]中获取的内容:

class DynamicFieldsModelSerializer(serializers.ModelSerializer):
   """
   A ModelSerializer that takes an additional `fields` argument that
   controls which fields should be displayed.
   """

   def __init__(self, *args, **kwargs):
       # Don't pass the 'fields' arg up to the superclass
       fields = kwargs.pop('fields', None)

       # Instantiate the superclass normally
       super().__init__(*args, **kwargs)

       if fields is not None:
           # Drop any fields that are not specified in the `fields` >argument.
           allowed = set(fields)
           existing = set(self.fields)
           for field_name in existing - allowed:
               self.fields.pop(field_name)

此外,您可以在您的 * 视图 * 中执行此操作,如以下代码片段所示:

my_dish = Dish.objects.get(pk=dish.id)
serializer = Dish_Serializer(my_dish)
desired_fields = {'id', 'name', 'description'}
all_fields = set(serializer.fields)
for field in all_fields:
    if field not in desired_fields:
        serializer.fields.pop(field)
my_new_object = serializer.data

相关问题