Отображение подмножеств «многие ко многим» с разными именами? в шаблоне Django

#django #many-to-many

#django #»многие ко многим»

Вопрос:

Я планирую избавиться от связанного имени при следующем восстановлении базы данных … модели, которые я использую, больше похожи на тестовые модели. Итак, с классом Creator и writer, cover_artist и т.д., Как бы я мог отобразить проблемы, созданные создателем (как только я избавлюсь от связанного имени, если только нет способа обойти это)?

 class Creator(models.Model):
    name = models.CharField(max_length=256)
    desc = models.TextField("description", blank=True, null=True)
    #type = writer, artist, editor, letterer
    slug = models.SlugField(blank=True, null=True)
    def __unicode__(self):
        return self.name
    class Meta:
        ordering = ['name']
    def get_absolute_url(self):
        return "/comics2/creators/%s" % self.slug 


class Issue(models.Model):
    ....
    writer = models.ManyToManyField(Creator, related_name="written by", help_text="Use cmd/ctrl   click to select multiple names. The same applies to the rest of the creators below.", blank=True, null=True)
    artist = models.ManyToManyField(Creator, related_name="drawn by", blank=True, null=True)
    cover_artist = models.ManyToManyField(Creator, related_name="cover drawn by", blank=True, null=True)
    colorist = models.ManyToManyField(Creator, related_name="colored by", blank=True, null=True)
    inker = models.ManyToManyField(Creator, related_name="inked by", blank=True, null=True)
    penciller = models.ManyToManyField(Creator, related_name="pencilled by", blank=True, null=True)
    letterer = models.ManyToManyField(Creator, related_name="lettered by", blank=True, null=True)
    editor = models.ManyToManyField(Creator, related_name="edited by", blank=True, null=True)
    arc = models.ManyToManyField(Arc, related_name="related story arc", blank=True, null=True)
    ...
    def __unicode__(self):
        return u'%s %s' % (self.title, self.number)
    def get_absolute_url(self):
        return "/comics2/issues/%s" % self.slug     
    class Meta:
        ordering = ['title', 'number']
    def get_stars(self):
        star_rating = self.rating * 16
        return star_rating
  

….

 {% for issue in creator.____?__.all %}
<ul>
<li>{{ issue }}</li>
</ul>    
{% endfor %}
  

Не сработает.

Спасибо.

Ответ №1:

Я бы посоветовал сменить ваши модели.py, чтобы иметь проблему, имеет отношение «Многие ко многим» к создателю через другую таблицу, например Role. Смотри docs здесь.

 class Creator(models.Model):
    name = models.CharField(max_length=256)
    desc = models.TextField("description", blank=True, null=True)
    slug = models.SlugField(blank=True, null=True)
    def __unicode__(self):
        return self.name
    class Meta:
        ordering = ['name']
    def get_absolute_url(self):
        return "/comics2/creators/%s" % self.slug 

class Issue(models.Model):
    creators = models.ManyToManyField(Creator, through='Role')
    arc = models.ManyToManyField(Arc, related_name="related story arc", blank=True, null=True)
    ...
    def __unicode__(self):
        return u'%s %s' % (self.title, self.number)
    def get_absolute_url(self):
        return "/comics2/issues/%s" % self.slug     
    class Meta:
        ordering = ['title', 'number']
    def get_stars(self):
        star_rating = self.rating * 16
        return star_rating

class Role(models.Model):
    issue = models.ForeignKey(Issue)
    creator = models.ForeignKey(Creator)
    role = models.CharField()
    ...
  

Редактировать:

в вашем представлении проблем вы бы получили разные роли и передали их своему шаблону (например):

 def issue_detail(request, issue_slug=None):
    issue = get_object_or_404(Issue, slug=creator_slug)
    writers = issue.creators.filter(role__role='writer')
    cover_artists = issue.creators.filter(role__role='cover artist')
    ...

    context = { 'issue': issue,
                'writers': writers,
                'cover_artists': cover_artists,
                ...
               }

    return render_to_response('issue_detail.html', context,
           context_instance=RequestContext(request))
  

шаблон:

 <label>Writers</label>
{% for writer in writers %}
    {{ writer }}
{% endfor %}
<label>Cover Artists</label>
{% for cover_artist in cover_artists %}
    {{ cover_artist }}
{% endfor %}
  

представление создателя:

 def creator_detail(request, issue_slug=None):
    creator = get_object_or_404(Creator, slug=issue_slug)
    issues_as_writer = creator.issue_set.filter(role__role='writer')
    issues_as_cover_artists = creator.issue_set.filter(role__role='cover artist')

    #all issues related to this creator
    all_issues = creator.issue_set.all()
    ...

    context = { 'creator': creator,
                'issues_as_writer': issues_as_writer,
                'issues_as_cover_artist': issues_as_cover_artist,
                ...
                'all_issues': all_issues,
               }

    return render_to_response('creator_detail.html', context,
           context_instance=RequestContext(request))
  

Комментарии:

1. Это кажется немного запутанным, потому что я не знаю, как Role Будет различать writer, artist и т.д. В шаблоне После просмотра примера модели на Django. Это то, что у меня есть прямо сейчас: amlaplant.webfactional.com/comics2/issues/astonishing-x-men-1

2. Спасибо. И это позволило бы мне отобразить проблемы, в которые был вовлечен создатель, с помощью шаблона? Как бы я это сделал?

3. Что, если Джон Смит является одновременно писателем и художником.. будет ли это все еще теоретически работать?