1

ЗадачаНевозможно импортировать сериализатор из другого сериализатора в django rest-framework?

У меня есть 2 модели, выводы и заметки. Я хочу, чтобы у вас было 1 или более нот. Я использовал общий внешний ключ, потому что я хочу планировать будущее, и, к примеру, можно назначить заметку для человека или собрания.

Следуя инструкциям для рамки django rest и общих компонентов Rest Framework, я пытаюсь импортировать один сериализатор из другого, чтобы сделать обратное отношение возможным.

Ошибка

Я не могу импортировать сериализаторы в обоих файлах (называют один сериализатору от другого), потому что я получаю:

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 

Его странно, потому что, если я открываю Джанго оболочки и выполните следующие действия, чтобы я мог импортировать их все:

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. .. посмотрите, куда это идет?

Ваш StackTrace говорит все:

from leads.serializers import LeadSerializer 

from notes.serializers import NoteSerializer 

from leads.serializers import LeadSerializer 

Генерация ImportError: не может импортировать имя LeadSerializer

То, что я сделал, чтобы решить эту проблему объявлял все сериализаторы в одном файле. Таким образом, у вас есть два варианта:

  1. Move LeadSerializer в ноты/serializers.py
  2. Move NoteSerializer для проводов/serializers.py

Это не самый элегантный способ Решите это, но он сделал свой трюк.


В разделе ниже, не дает никаких дальнейших объяснений о том, как решить эту проблему, но наблюдение по этому вопросу.

Возможно Джанго & DRF может futurely обеспечить способы, чтобы избежать этого, например, объявив сериализаторы, как

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

или

notes = 'notes.serializers'.NoteSerializer(many=True, read_only=True) 

 Смежные вопросы

  • Нет связанных вопросов^_^