我已在 OneToOne 字段中设置了 related_name,但仍然收到相关对象DoesNotExist 错误

air*_*aft 4 python django django-rest-framework

当我使用时to_representation出现错误:

\n\n
\n

django.db.models.fields.lated_descriptors.RelatedObjectDoesNotExist:SwitchesPort没有physical_server。

\n
\n\n

回溯如下:

\n\n
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/rest_framework/serializers.py", line 656, in <listcomp>\n    self.child.to_representation(item) for item in iterable\n  File "/Users/asd/Desktop/xxx/api/serializers.py", line 256, in to_representation\n    if instance.physical_server == None:\n  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/django/db/models/fields/related_descriptors.py", line 407, in __get__\n    self.related.get_accessor_name()\ndjango.db.models.fields.related_descriptors.RelatedObjectDoesNotExist: SwitchesPort has no physical_server.\n
Run Code Online (Sandbox Code Playgroud)\n\n

我的模特:

\n\n
class SwitchesPort(models.Model):\n    """\n    \xe4\xba\xa4\xe6\x8d\xa2\xe6\x9c\xba\xe6\x8e\xa5\xe5\x8f\xa3\n    """\n    ...\n    switches = models.ForeignKey(to=Switches, on_delete=models.CASCADE,related_name="switchesports", help_text="\xe6\x89\x80\xe5\xb1\x9e\xe4\xba\xa4\xe6\x8d\xa2\xe6\x9c\xba")\n    vlanedipv4networkgroup = models.ForeignKey(\n        to=VlanedIPv4NetworkGroup, # \xe5\x88\x9d\xe5\xa7\x8b\xe5\x8c\x96\xe4\xb9\x8b\xe5\x90\x8e\xe7\x9a\x84\n        null=True,\n        blank=True,\n        on_delete=models.SET_NULL,\n        related_name="switchesports",\n        help_text="\xe6\x89\x80\xe5\x85\xb3\xe8\x81\x94\xe7\x9a\x84vlaned\xe7\xbb\x84")\n\n    network_speed = models.IntegerField(default=10, help_text="\xe4\xba\xa4\xe6\x8d\xa2\xe6\x9c\xba\xe6\x8e\xa7\xe5\x88\xb6\xe7\xbd\x91\xe7\xbb\x9c\xe6\xb5\x81\xe9\x87\x8f\xe9\x80\x9f\xe5\xba\xa6")\n\n    class Meta:\n        ordering = [\'name\']\n\n    def __str__(self):\n        return self.name\n    def __unicode__(self):\n        return self.name\n\nclass PhysicalServer(models.Model):\n    """\n    physical_server\n    """\n    ...\n\n    switchesport = models.OneToOneField(to=SwitchesPort, related_name="physical_server", on_delete=models.DO_NOTHING, help_text="\xe6\x89\x80\xe5\xb1\x9e\xe4\xba\xa4\xe6\x8d\xa2\xe6\x9c\xba\xe6\x8e\xa5\xe5\x8f\xa3",\n                                     null=True)   \n\n    def __str__(self):\n        return self.name\n\n    def __unicode__(self):\n        return self.name\n
Run Code Online (Sandbox Code Playgroud)\n\n

我的序列化器如下:

\n\n
class SwitchesPortSerializer(ModelSerializer):\n    """\n    switches port \n    """\n    class Meta:\n        model = SwitchesPort\n        fields = "__all__"\n        extra_kwargs = {\n            "vlaned_network":{"read_only":True}\n        }\n\n    def to_representation(self, instance):\n        serialized_data = super(SwitchesPortSerializer, self).to_representation(instance)    \n\n        if instance.physical_server == None:    # there syas the error\n            serialized_data[\'is_connected\'] = True\n\n        return serialized_data\n
Run Code Online (Sandbox Code Playgroud)\n\n

你看,OneToOne 字段有related_name,为什么我仍然遇到这个问题?

\n

Ala*_*air 6

if instance.physical_server == None:
Run Code Online (Sandbox Code Playgroud)

这是行不通的,因为instance.physical_server如果该实例没有相关的,则会引发异常PhysicalServer

您可以通过将支票更改为以下方式来解决问题:

if hasattr(instance, 'physical_server'):
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请参阅有关一对一关系的文档。