Django Rest Framework, реализующий отношения «многие ко многим»

Я хочу реализовать отношения many to many, чтобы один человек мог присоединиться к нескольким социальным клубам, а один социальный клуб мог иметь несколько членов. Вот как далеко я продвинулся, но это не отображает детали фильма, а сериализация дает мне ошибку -
Original exception text was: 'ManyRelatedManager' object has no attribute 'club_name'.

models.py

class Club(models.Model):
  club_name = models.CharField(default='',blank=False,max_length=100)

class Person(models.Model):
  person_name = models.CharField(default='',blank=False,max_length=200)
  clubs = models.ManyToManyField(Club)

serializers.py

class ClubSerializer(serializers.ModelSerializer):
  class Meta:
    model = Club
    fields = ('url','id','club_name','person')

class PersonSerializer(serializers.ModelSerializer):
  clubs = ClubSerializer()
  class Meta:
    model = Person
    fields = ('url','id','person_name','clubs')

views.py

class ClubDetail(generics.ListCreateAPIView):
serializer_class = ClubSerializer

  def get_queryset(self):
    club = Clubs.objects.get(pk=self.kwargs.get('pk',None))
    persons = Person.objects.filter(club=club)
    return persons

class ClubList(generics.ListCreateAPIView):
  queryset = Club.objects.all()
  serializer_class = ClubSerializer


class PersonDetail(generics.RetrieveUpdateDestroyAPIView):
  serializer_class = PersonSerializer


def get_object(self):
  person_id = self.kwargs.get('pk',None)
  return Person.objects.get(pk=person_id) 

urls.py

urlpatterns = format_suffix_patterns([
url(r'^$', views.api_root),
url(r'^clubs/$',
views.ClubList.as_view(),
name='club-list'),
url(r'^clubs/(?P<pk>[0-9]+)/persons/$',
views.ClubDetail.as_view(),
name='club-detail'),
url(r'^person/(?P<pk>[0-9]+)/$',
views.PersonDetail.as_view(),
name='person-detail'),
])

на моем локальном сервере я получаю список клубов, который перенаправляет меня к просмотру Clubdetail, но он не показывает названия фильмов или, но я не вижу список людей. Как мне это сделать правильно?


person qwertp    schedule 23.12.2015    source источник


Ответы (2)


У вас есть ряд проблем в вашем коде здесь. А именно:

  • ClubSerializer.Meta.fields — человек должен быть person_set
  • PersonSerializer - клубы должны быть clubs = ClubSerializer(many=True)
  • ClubDetail.serializer_class — ClubSerializer должен быть PersonSerializer
  • ClubDetail — набор запросов должен быть persons = Person.objects.filter(clubs=club)

Если вы исправите вышеперечисленное, вы сможете перейти к ClubDetail и увидеть список членов клуба.

person Ashley 'CptLemming' Wilson    schedule 23.12.2015
comment
point1: я получаю следующую ошибку: Field name person_set` недействителен для модели `Club`` - person qwertp; 24.12.2015
comment
Эта строка clubs = models.ManyToManyField(Club) автоматически создает связанное имя person_set. Вы действительно должны иметь это поле доступным, используя код, который вы разместили выше. - person Ashley 'CptLemming' Wilson; 24.12.2015
comment
Кроме того, пункт 3: дает мне информацию об одном человеке с подробностями о нескольких клубах, в которых он состоит, тогда как я хотел получить информацию о клубах с разными людьми. И при нажатии на одного из этих людей, сведения о человеке основаны на представлении. - person qwertp; 24.12.2015
comment
Вы записали ClubDetail как ListCreateAPIView, который возвращает список Person, отфильтрованный по клубам. Если я реализую ваш код (с изменениями в 3 и 4), я получаю список, как описано. Если это не то, что вы хотите, возможно, вам придется переосмыслить эту точку зрения. - person Ashley 'CptLemming' Wilson; 24.12.2015
comment
Смотрите, что я хотел, это 3 API /clubs /club/<pk>/details/ и /persons/<pk> - persons in a particular club . Не могли бы вы объяснить, какие изменения мне нужно внести, чтобы добиться этого. Спасибо, что объяснили и ответили на столько вопросов. Был на нем в течение нескольких часов. - person qwertp; 24.12.2015
comment
Итак, я понимаю, что вы хотите, чтобы ClubList перечислял клубы, PersonDetail представлял одного человека, но что именно вы хотите от ClubDetail? Должен ли это быть список лиц в клубе или это должна быть информация о клубе со списком лиц, вложенным в ответ? - person Ashley 'CptLemming' Wilson; 24.12.2015
comment
Точно. это должен быть список людей в клубе. - person qwertp; 24.12.2015

Если вы используете отношения «многие ко многим», обязательно явно объявите поле, например:

class WidgetSerializer(serializers.HyperlinkedModelSerializer):
    
    parts__part = serializers.CharField()
    

    class Meta:
        model = Widget
        fields = ['date', 'url', 'type','parts__part']
person Ben Wilson    schedule 19.01.2021