25

The model defines an Article and an Author classes. They are linked together with a many-to-many relationship. This relationship is defined through an custom intermediary table:

# models.py
class Article(models.Model):
    title = models.CharField(max_length=500)
    authors = models.ManyToManyField(Author, through='AuthorOrder')

class Author(models.Model):
    name = models.CharField(max_length=255)

class AuthorOrder(models.Model):
    author = models.ForeignKey(Author)
    article = models.ForeignKey(Article)
    writing_order = models.IntegerField()

The serialization should return a JSON like this:

#articles_json
{"fields":
     {
         "title": "A title",
         "authors": [
             {
                 "name":"Author 1",
                 "writing_order": 1
             },
             {
                 "name":"Author 2",
                 "writing_order": 2
             }
         }
     }
}

I've identified two solutions.

I tried the twos but without success. Do you know another way to do it?

Community
  • 1
  • 1
pzijd
  • 781
  • 1
  • 6
  • 9
  • "Using the DRF" is the right thing to do, but it is not a solution. What format exactly do you want for your serialised data? – Daniel Roseman Feb 01 '17 at 10:14
  • "But without success" would be the point where you should provide more details (how did you do it and what was the error) to make this a real SO question. – Risadinha Feb 01 '17 at 10:23
  • 1
    For DRF see http://stackoverflow.com/questions/19180242/how-to-serialize-using-django-rest-framework-a-manytomanyfields-with-a-through-m – Risadinha Feb 01 '17 at 10:27

1 Answers1

39

Thanks to your feedback, I focused on Django REST framework and it works. Here are the custom serializers I've written:

# serializers.py
from rest_framework import serializers
from app.models import Article, AuthorsOrder


class AuthorsOrderSerializer(serializer.ModelSerializer):
    author_name = serializers.ReadOnlyField(source='author.name')

    class Meta:
        model = AuthorsOrder
        fields = ('writing_order', 'author_name')


class ArticleSerializer(serializer.ModelSerializer):
    authors = AuthorsOrderSerializer(source='authorsorder_set', many=True)

    class Meta:
        model = Article
        fields = ('title', 'authors')

Sources:

  1. Include intermediary (through model) in responses in Django Rest Framework
  2. https://bitbucket.org/snippets/adautoserpa/MeLa/django-rest-framework-manytomany-through
Syed Shamikh Shabbir
  • 1,252
  • 1
  • 14
  • 18
pzijd
  • 781
  • 1
  • 6
  • 9
  • But this does not give out the authors in the correct order, does it? – David Schumann Nov 07 '17 at 07:57
  • Yes it does. Thanks to the AuthorsOrderSerializer instance. – pzijd Nov 08 '17 at 14:08
  • 4
    Where did "authorsorder_set" come from?? – Panagiss May 16 '21 at 09:25
  • Hi @pzijd, Here, the author name would be like: `title: "some title, authors: [{"name": "some name 1"}, {"name": "some name 2"}]` Can we have something like: `[{"title": "some title", "author_name": "some name 1"}, {"title": "some title", "author_name": "some name 2"}]` – Reema Parakh Oct 08 '21 at 09:07
  • @Panagiss Leaving the source='...' out did enough for me. :) – Peetha Mar 16 '22 at 15:06
  • 1
    @Panagiss `authorsorder_set` is (a slightly misspelled) implicit `related_name` for the `AuthorOrder.author` field. It should be spelled `authororder_set` – Thismatters Aug 16 '22 at 15:29