I
I
Ilya Oskin2016-07-20 18:25:54
Django
Ilya Oskin, 2016-07-20 18:25:54

How to bind multiple submodels to one model in Django?

Hello! I am making a single page application on Django 1.9 (with rest framework). The essence of the problem is this:
There are only two models Case (Cases) and Article (Many articles about each case), on the main page only a list of previews for Cases is displayed. But on the page with a detailed description of a particular case, in addition to information from the Case model itself, you need to display several Article instances of this case, and here questions arise. To then pass all the data to the appropriate template, I use a serializor:

from rest_framework import serializers
from landing.models import Case, Article

class CasePreviewSerializer(serializers.ModelSerializer):
    class Meta:
        model = Case
        fields = [
            'id',
            'name',
            'preview',
            'slider_preview',
            'url',
        ]

class CaseDetailSerializer(serializers.ModelSerializer):
    class Meta:
        model = Case
        fields = [
            'name',
            'slider_preview',
        ]
    class Meta:
        model = Article
        fields = [
            'picture',
            'caption',
        ]

As you can see from this piece of code, in the CaseDetailSerializer class, I naively try to define the Meta class twice - first for the Case model, and then for the Article model, in order to get all the data necessary for the view, but Django throws an error.
models.py:
from django.db import models
from django.utils.translation import ugettext_lazy as _

class Case(models.Model):
    name = models.CharField(_('case name'), max_length=30)
    preview = models.ImageField(_('preview image'), upload_to="images")
    created_at = models.DateTimeField(_('created at'), auto_now_add=True)
    slider = models.BooleanField(_('is slider preview availible'))
    if slider:
        slider_preview = models.ImageField(_('slider preview'), upload_to="images")

    def __str__(self):
        return self.name

class Article(models.Model):
    case = models.ForeignKey(Case)
    picture = models.ImageField(_('picture'), upload_to="images")
    caption = models.TextField(_('text'), max_length=501)

    def __str__(self):
        return self.caption

views.py
from rest_framework import viewsets
from .serializers import *

class CaseViewSet(viewsets.ReadOnlyModelViewSet):
    queryset = Case.objects.all()

    def get_serializer_class(self):
        if self.action == 'list':
            return CasePreviewSerializer
        return CaseDetailSerializer

Perhaps I am fundamentally wrong in implementing such a concept (so that each Case instance has many Article instances)?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
A
Abdulla Mursalov, 2016-07-20
@Oskin1

The Case and Article models must be associated with a ForeignKey.

class Article(models.Model):
    ...
    case = models.ForeignKey(Case, related_name='articles')
    ...

Now in the serializer CaseSerializer you can display relationships as a PrimaryKeyRelation or using a nested serializer
class CaseSerializer(serializers.ModelSerializer):
    class Meta:
        model = Case
        fields = (..., ..., 'articles')

Read related docs

E
Evgeny Maltsev, 2016-07-20
@hellpirat

In case:
articles = models.ManyToMany(Article)

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question