这是一个简单的问题,但我对django-rest-framework非常新。
我想知道是否有办法从序列化程序访问模型上定义的方法。?
说我有模特
class Listing(models.Model):
listingid = models.BigIntegerField(primary_key=True)
mappingid = models.BigIntegerField()
projectlevelid = models.IntegerField()
subsellerid = models.IntegerField()
iscreatedbyadmin = models.BooleanField(default=None, null=True)
createdon = models.DateTimeField(auto_now_add=True, editable=False)
validationstatus = models.SmallIntegerField(default=0)
def is_project(self):
""" Returns True if listing is of Project Type (projectlevelid=6) else False"""
if self.projectlevelid == 6:
return True
else:
return False
def get_project_info(self):
"""Returns False if listing is not mapped to a project, else returns the project info"""
if self.is_project() == False:
return False
return models.Project.objects.get(projectid=self.mappingid)
是否可以使用序列化程序
class ListingSerializer(serializers.ModelSerializer):
class Meta:
model = models.MasterListing
有权访问Listing.is_project
,即对于Listing
模型的对象,序列化程序可以调用其is_project
方法吗?
如果是这样,我可以在序列化程序中设置一个字段,以便如果is_project
返回true,那么该字段是否已填充?
我正在尝试这样的事情,
class ListingSerializer(serializers.ModelSerializer):
project = serializers.SomeRELATEDFieldTYPE() # this field if populated if the `is_project` is true
class Meta:
model = models.MasterListing
我知道我可以使用required=False
和SerializerMethodField
的某种组合来完成此操作,但是可能有更简单的方法吗?
注意:我无法将外键设置为mappingid
,因为它取决于projectlevelid
。我也不能影响这种关系,因此不可能进一步标准化。我知道可能有某种方式使用内容类型,但我们试图避免这种情况,如果有可能..
编辑:我解决了问题,但没有解决问题。 我用过这个:
class ListingSerializer(serializers.ModelSerializer):
project = serializers.SerializerMethodField()
def get_project(self, obj):
"""Returns False if listing is not mapped to a project, else returns the project info"""
if str(obj.projectlevelid) == str(6):
projectObj = models.Project(projectid=obj.mappingid)
projectObjSerialized = ProjectSerializer(projectObj)
return projectObjSerialized.data
return False
class Meta:
model = models.MasterListing
所以,最初的问题仍然存在:“modelSerializer是否可以访问其模型方法?”
此外,现在出现的另一个问题是,可以让序列化程序按需排除字段,即如果它确实是项目,它是否可以排除mappingid
和projectlevelid
?
答案 0 :(得分:6)
对于您的第一个问题source属性是答案,引用:
可能是一个只接受自我参数的方法,例如 URLField( 'get_absolute_url')
对于你的第二个答案,是的,它也是可能的。请查看其文档中提供的示例:http://www.django-rest-framework.org/api-guide/serializers/#dynamically-modifying-fields
PS:我非常喜欢drf的完整文档=)。
修改强>
要使用source属性,您只需声明一个新的显式字段,如下所示:
is_project = serializers.BooleanField(source='is_project')
这样,is_project字段具有实例的is_project方法的值。有了这个,在创建动态序列化程序时(通过修改它的init方法),你可以添加'project'字段,如果它是真的。
答案 1 :(得分:0)
@argaen是绝对正确的,surname.replace('\n', '')
是DRF的核心论点,绝对可以解决您的问题。但是,如果字段名称与source
相同,则使用source
是多余的。因此,上面的答案不需要您指定source
,因为source
名称field
与is_project
名称source
相同。
所以在您的情况下:
is_project