1

問題無法從django rest-framework中的其他序列化程序導入序列化程序?

我有2個模型,主角和筆記。我想要一名潛在客戶能夠擁有1個或更多筆記。我已經使用了一個通用的外鍵,因爲我想爲未來做計劃,並且可以將一個筆記分配給一個人或一個會議。

遵循django rest框架和rest框架通用關係的說明我試圖從另一個導入一個序列化程序以使反向關係成爲可能。

錯誤

我不能導入序列化在這兩個文件(調用來自另一個串行),因爲我得到:

File "/Users/james/Documents/UtilityCRM-Server/crm/leads/urls.py", line 2, in <module> 
    from leads import views 
    File "/Users/james/Documents/UtilityCRM-Server/crm/leads/views.py", line 11, in <module> 
    from leads.serializers import LeadSerializer 
    File "/Users/james/Documents/UtilityCRM-Server/crm/leads/serializers.py", line 4, in <module> 
    from notes.serializers import NoteSerializer 
    File "/Users/james/Documents/UtilityCRM-Server/crm/notes/serializers.py", line 6, in <module> 
    from leads.serializers import LeadSerializer 
ImportError: cannot import name LeadSerializer 

它的奇怪,因爲如果我打開Django的殼運行以下它可以讓我將它們全部導入:

from leads.serializers import LeadSerializer 
from notes.serializers import NotesSerializer 
from callbacks.serializers import CallbackSerializer 

任何幫助將不勝感激!

代碼

這是我的設置文件我安裝的應用程序部分:

INSTALLED_APPS = [ 
    'django.contrib.admin', 
    'django.contrib.auth', 
    'django.contrib.contenttypes', 
    'django.contrib.sessions', 
    'django.contrib.messages', 
    'django.contrib.staticfiles', 
    # 3rd Party Apps 
    'rest_framework', 
    'generic_relations', 
    # My Apps 
    'leads.apps.LeadsConfig', 
    'callbacks.apps.CallbacksConfig', 
    'notes.apps.NotesConfig', 
] 

筆記/ models.py

from __future__ import unicode_literals 

from django.db import models 
from django.utils import timezone 
from django.contrib.contenttypes.fields import GenericForeignKey 
from django.contrib.contenttypes.models import ContentType 

class Note(models.Model): 
    author = models.ForeignKey('auth.User') 
    title = models.CharField(max_length=100) 
    text = models.TextField() 
    created_date = models.DateTimeField(default=timezone.now) 

    # Relations 
    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) 
    object_id = models.PositiveIntegerField() 
    note_object = GenericForeignKey('content_type', 'object_id') 

    def __str__(self): 
     return self.title 

引線/ models.py

from __future__ import unicode_literals 

from django.db import models 
from django.contrib.contenttypes.fields import GenericRelation 
from django.utils import timezone 

from notes.models import Note 
from callbacks.models import Callback 

GAS = 'G' 
ELECTRICITY = 'E' 
LEAD_TYPE_CHOICES = (
    (GAS, 'Gas'), 
    (ELECTRICITY, 'Electricity'), 
) 

# Create your models here. 
class Lead(models.Model): 

    author = models.ForeignKey('auth.User') 
    type = models.CharField(
     max_length=1, 
     choices=LEAD_TYPE_CHOICES, 
     default=GAS, 
    ) 
    business_registration_number = models.IntegerField(max_length=20) 
    business_name = models.CharField(max_length=50) 
    mpan = models.IntegerField(max_length=21) 
    supplier = models.CharField(max_length=45) 
    contract_length = models.IntegerField(max_length=2) 
    contract_start_date = models.DateField() 
    contract_end_date = models.DateField() 
    address_line_1 = models.CharField(max_length=45) 
    address_line_2 = models.CharField(max_length=45) 
    address_line_3 = models.CharField(max_length=45) 
    address_city = models.CharField(max_length=45) 
    address_county = models.CharField(max_length=45) 
    address_postcode = models.CharField(max_length=10) 
    contact_title = models.CharField(max_length=45) 
    contact_first_name = models.CharField(max_length=45) 
    contact_middle_name = models.CharField(max_length=45) 
    contact_last_name = models.CharField(max_length=45) 
    contact_telephone = models.IntegerField(max_length=11) 
    contact_email = models.EmailField(max_length=60) 
    created_date = models.DateTimeField(default=timezone.now) 

    # Relations 
    assigned_to = models.ForeignKey('auth.User', related_name='+') 
    #from_batch = models.ForeignKey('data_batch.DataBatch', related_name='+') 
    #callbacks = GenericRelation(Callback) 
    notes = GenericRelation(Note) 

    class Meta: 
     ordering = ('contract_end_date', 'business_name',) 

    def __str__(self): 
     return self.business_name 

我有2個串行:

引線/ serializers.py

from rest_framework import serializers 
from leads.models import Lead, LEAD_TYPE_CHOICES 

from notes.serializers import NoteSerializer 

class LeadSerializer(serializers.ModelSerializer): 
    notes = NoteSerializer(many=True, read_only=True) 

    class Meta: 
     model = Lead 
     fields = (
      'id', 
      'business_name', 
      'business_registration_number', 
      'supplier', 
      'contract_length', 
      'contract_start_date', 
      'notes' 
      ) 

筆記/ serializers.py

from generic_relations.relations import GenericRelatedField 
from rest_framework import serializers 
from notes.models import Note 

from leads.models import Lead 
from leads.serializers import LeadSerializer 

from callbacks.models import Callback 
from callbacks.serializers import CallbackSerializer 


class NoteSerializer(serializers.ModelSerializer): 
    """ 
    A `Note` serializer with a `GenericRelatedField` mapping all possible 
    models to their respective serializers. 
    """ 
    note_object = GenericRelatedField({ 
     Lead: LeadSerializer(), 
     Callback: CallbackSerializer() 
    }) 

    class Meta: 
     model = Note 
     fields = (
      'id', 
      'author', 
      'title', 
      'text', 
      'created_date', 
      'note_object', 
      ) 
+0

你如何註冊內settings.py您的應用程序[我的意思是在INSTALLED_APPS] – Cadmus

+0

我已編輯我的問題幷包含此信息。 –

+0

我相信這是由於python中的循環(循環)導入。我面臨同樣的問題,但我不喜歡按照@Cadmus的建議重新安排我的項目結構。你有沒有設法找到解決方案? – Cortifero

回答

1

有一個想法來解決這個在我也有這個相同的錯誤之前,我會向你解釋我是如何解決這個問題的。

把你的應用程序項目目錄內

project 
    -project 
    -appname1 
     -models.py 
     -serilizer.py 
    -appname2 
    -models.py 
    -serilizer.py 
    -settings.py 
settings.py中

INSTALLED_APPS = ['project.appname1', 'project.appname2'] 

然後嘗試串行輸入APPNAME1到appname2

這樣

from project.appname1.serializers import(ArtistSerializer, ArtisTokenSerilizer, ProfessionSerilizer, FollowersSerializer, 
      FollowingSerializer, ChatMessageSerializer, SendMessageSerializer, ConversationMessageSerializer, 
      ProjectTypeSerializer) 
+0

感謝您的回覆。 我在上面的問題中添加了更多細節。 我剛試過把它們都放在我的項目的根目錄下無濟於事。 我找不到任何文檔/教程,其中有一個將序列化程序從一個應用程序導入另一個應用程序的示例。這讓我覺得我做錯了嗎? –

0

正如我之前在評論中提到的,我相信這是由於Python中的循環(循環)導入而發生的。 特別是當您在模型中聲明相關字段時,會發生這種情況,並且某些模型尚未實例化。

在這種情況下,當你執行你的程序,它會嘗試導入LeadSerializer,需要進口NoteSerializer,需要進口LeadSerializer,需要進口NoteSerializer。 ..看看這是怎麼回事?

你的堆棧跟蹤了一切:

from leads.serializers import LeadSerializer 

from notes.serializers import NoteSerializer 

from leads.serializers import LeadSerializer 

生成導入錯誤:無法導入名稱LeadSerializer

我做了什麼來解決這個被宣佈所有串行在一個文件中。因此,你有兩個選擇:

  1. 移動LeadSerializer到Notes/serializers.py
  2. 移動NoteSerializer到引線/ serializers.py

它是不是最優雅的方式來解決這個問題,但它已經做到了。


以下部分提供了關於如何解決這個問題沒有進一步的解釋,但對這個問題的觀察。

或許Django的& DRF可以futurely提供的方法來避免這種情況,如宣佈串行作爲

note_object = GenericRelatedField({ 
    Lead: 'leads.serializers'.LeadSerializer, 
    Callback: CallbackSerializer() 
}) 

notes = 'notes.serializers'.NoteSerializer(many=True, read_only=True) 
相關問題