Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django - Access fields on a model's "through" table from an instance

I have a many-to-many relationship with a through table like so:

class Chapter(models.Model):
    name = models.CharField(max_length=255,)
    slides = models.ManyToManyField('Slide', blank=True, related_name='chapters', through='SlideOrder')
    # ...

class Slide(models.Model):
    title = models.CharField(max_length=255,)
    # ...

class SlideOrder(models.Model):
    chapter = models.ForeignKey(Chapter)
    slide = models.ForeignKey(Slide)
    number = models.PositiveIntegerField()

I am able to get the slides for a chapter in order like so:

chapter = Chapter.objects.get(pk=1)
chapter_slides = chapter.slides.order_by('slideorder')

However, when working on an individual slide instance I am unable to access the slide order:

slide = Slide.objects.get(pk=1)

If I do the following on my slide instance I can see all possible fields:

print slide._meta.get_all_field_names()
['title', u'chapters', 'slideorder', u'id']

However trying to access the slideorder field gives me the following:

slide.slideorder
Traceback (most recent call last):
  File "<console>", line 1, in <module>
AttributeError: 'Slide' object has no attribute 'slideorder'

I am able to access all attributes listed except slideorder. How can I access a slide's order?

like image 609
tsantor Avatar asked Jul 07 '15 15:07

tsantor


People also ask

How do you get or view all the items in a model in Django?

The simplest way you can get the list of objects of an attribute is to first get a query-set of that attribute alone using values_list then converting the django query-set to a python set using set() and finally to a list using list() .

What is the purpose of __ Str__ method in Django?

str function in a django model returns a string that is exactly rendered as the display name of instances for that model. # Create your models here. This will display the objects as something always in the admin interface.

What is Get_absolute_url in Django?

Django documentation says: get_absolute_url() method to tell Django how to calculate the canonical URL for an object.

What is proxy model in Django?

A proxy model is a subclass of a database-table defining model. Typically creating a subclass of a model results in a new database table with a reference back to the original model's table - multi-table inheritance. A proxy model doesn't get its own database table. Instead it operates on the original table.


2 Answers

You can either filter on the SlideOrder model directly

slide = Slide.objects.get(pk=1)
slide_orders = SlideOrder.objects.filter(slide=slide)
for slide_order in slide_orders:
    print slide_order.number

or follow the foreign key backwards:

slide = Slide.objects.get(pk=1)
slide_orders = slide.slideorder_set.all()
for slide_order in slide_orders:
    print slide_order.number

See the docs on extra fields on many-to-many relationships for more info.

like image 145
Alasdair Avatar answered Nov 14 '22 23:11

Alasdair


You can use slide.slideorder_set as documented in the django docs

like image 32
Ward Avatar answered Nov 15 '22 00:11

Ward