Объекты-повторители, появляющиеся во всех подробных представлениях — django

#django #django-models #django-admin

#django #django-модели #django-администратор

Вопрос:

У меня есть две модели с внешним ключом, отношение «один ко многим», чтобы я мог получить модель повторителя (изображения) в admin. Повторитель изображений работает нормально, моя проблема в том, что изображения для field — video_stills, сохраненные в одном из записей / объектов фильма, повторяются во всех записях фильма.

Вот мой код:

model.py

 from __future__ import unicode_literals
from django.db import models
from embed_video.fields import EmbedVideoField
from sorl.thumbnail import ImageField

class Timestamp(models.Model):
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

    class Meta:
        abstract = True

# Film Model
class Film(Timestamp):
    title = models.CharField(max_length=255)
    order = models.PositiveIntegerField(default=0, blank=False, null=False)
    meta_description = models.TextField('Meta Description', max_length=170, 
        help_text='Content for description meta tag - Max 170 Characters')
    slug = models.SlugField(unique=True)
    image = models.ImageField(upload_to='thumb')
    video = EmbedVideoField(blank=True)
    director = models.CharField(max_length=255,blank=True)
    cinematographer = models.CharField(max_length=255,blank=True)
    producer = models.CharField(max_length=255,blank=True)

    publish = models.BooleanField(default=False)
    date_published = models.DateTimeField()

    # thumb for admin
    def image_thumb(self):
        return '<img src="%s" height="200" width="300"/>' % (self.image.url)
    image_thumb.short_description = 'Image'
    image_thumb.allow_tags = True

    # override the admin name   add ordering
    class Meta(object):
        ordering = ('order',)
        verbose_name_plural = "Film Projects"

    def __unicode__(self):
        return self.title

    # helper method
    def get_absolute_url(self):
        return "/film/%s/" % self.slug

    def save(self, *args, **kwargs):
            super(Film, self).save(*args, **kwargs)

# Film Stills Image Model
class FilmStillsImage(models.Model):
    video_stills = models.FileField(upload_to = 'images')
    film = models.ForeignKey(Film)

    class Meta(object):
        verbose_name_plural = "Film Stills"
  

views.py

 # film single
def film_detail(request, slug):

    film = get_object_or_404(Film, slug=slug)

    # get all repeater images
    film_grabs = FilmStillsImage.objects.all()

    try:
        next_film = film.get_next_by_date_published()
    except Film.DoesNotExist:
        next_film = None

    try:
        previous_film = film.get_previous_by_date_published()
    except Film.DoesNotExist:
        previous_film = None

    return render(request, 'film/film_detail.html', {
        'film': film,
        'film_grabs': film_grabs,
        'next_film': next_film,
        'previous_film': previous_film
    })
  

film_detail.html

             <div class="section project-stills">
                {% if film_grabs %}
                <div class="row">
                        {% for filmstillsimage in film_grabs %}
                        <div class="grid-item four">
                            {% thumbnail filmstillsimage.video_stills "600x338" crop="center" as im %}
                                <img src="{{ im.url }}">
                            {% endthumbnail %}
                        </div>
                        {% if forloop.counter|divisibleby:4 %}
                     </div>
                 <div class="row">
                    {% endif %}
                        {% endfor %}
                 </div>
                {% else %}
                    <p>Nothing found.</p>
                {% endif %}
            </div>
  

admin.py

 class FilmStillsImageAdmin(admin.ModelAdmin):
    pass

class FilmStillsImageInline(admin.StackedInline):
    model = FilmStillsImage
    max_num = 8
    extra = 0

class FilmAdmin(SortableAdminMixin, admin.ModelAdmin):
    model = Film
    list_display = ('title', 'meta_description', 'image_thumb', 'video', 'director', 'cinematographer', 'producer', )

    inlines = [FilmStillsImageInline]

    prepopulated_fields = {'slug': ('title',)}
  

Я уверен, что это простое исправление, у меня такое чувство, что это из-за objects.all () в моих представлениях, заполняющих его для каждого элемента.

Извиняюсь, если это глупый вопрос, и спасибо за любую помощь!!

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

1. Боюсь, это не совсем понятно. Где повторяются изображения фильма?

2. Извините, если я не был ясен. Изображения для связанного поля ‘video_stills’ отображаются в каждом элементе фильма или публикации (подробный просмотр), даже если они не были сохранены в каждом элементе. Я надеюсь, что это имеет смысл!

Ответ №1:

Вы передаете все снимки фильма в шаблон detail, поэтому, естественно, все они будут отображаться. Вместо этого вы должны просто следовать обратному отношению в шаблоне, чтобы показать те, которые действительно связаны:

FilmStillsImage

 <div class="section project-stills">
      <div class="row">
          {% for filmstillsimage in film.filmstillsimage_set.all %}
               ....
  

и вообще нет необходимости передавать film_grabs из представления.

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

1. Большое тебе спасибо, Дэниел, действительно ценю это, легенда!! Просто еще один вопрос, является ли мой подход лучшим способом заставить изображения повторно загружаться в admin? Еще раз приветствую!

2. Я не уверен, что вы подразумеваете под «повторной загрузкой», но это стандартный способ установить отношение «один ко многим».

3. Я имел в виду многократную загрузку изображений через администратора с использованием отношения «один ко многим». Я новичок в django и перехожу на WP, у них есть плагин Advanced Custom Fields для обеспечения этой функциональности…