Django模板一次渲染我的所有文件

时间:2018-01-19 22:04:25

标签: python django

我现在对这个问题感到困惑了一段时间。它是这样的:我有一个带讲座的模型。我希望每个讲座能够上传多个文件,所以我创建了一个具有FileField的模型。因此,在我的模板中,我希望每次演讲都能显示和下载文件。问题是,每个讲座都会显示管理面板中上传过的所有文件。这是我的代码:

StorageMgr
trait Component: Debug + Sized + Any {
    type Storage: Storage<Self>;
}

trait Storage<T: Debug>: Debug + Any {
    fn new() -> Self
    where
        Self: Sized;

    fn insert(&mut self, value: T);
}

struct StorageMgr {
    storages: HashMap<TypeId, Box<Any>>,
}

impl StorageMgr {
    pub fn new() -> Self {
        Self {
            storages: HashMap::new(),
        }
    }

    pub fn get_storage_mut<C: Component>(&mut self) -> &mut <C as Component>::Storage {
        let type_id = TypeId::of::<C>();

        // Add a storage if it doesn't exist yet
        if !self.storages.contains_key(&type_id) {
            let new_storage = <C as Component>::Storage::new();

            self.storages.insert(type_id, Box::new(new_storage));
        }

        // Get the storage for this type
        match self.storages.get_mut(&type_id) {
            Some(probably_storage) => {
                // Turn the Any into the storage for that type
                match probably_storage.downcast_mut::<<C as Component>::Storage>() {
                    Some(storage) => storage,
                    None => unreachable!(), // <- you may want to do something less explosive here
                }
            }
            None => unreachable!(),
        }
    }
}
class Lecture(models.Model):
    course = models.ForeignKey('Course', on_delete=models.CASCADE, default='', related_name='lectures')
    lecture_category = models.IntegerField(choices=((0, "Classes "),
                                                    (1, "Seminars"),
                                                    ), default=0)
    lecture_title = models.CharField(max_length=100)
    content = models.TextField()
    files = models.OneToOneField('FileUpload', on_delete=models.CASCADE, null=True, blank=True, )

    def __str__(self):
        return str(self.lecture_category)


class FileUpload(models.Model):
    files = models.FileField(upload_to='documents', null=True, blank=True)

    def __str__(self):
        return str(self.files)

    def file_link(self):
        if self.files:
            return "<a href='%s'>download</a>" % (self.files.url,)
        else:
            return "No attachment"

    file_link.allow_tags = True
    file_link.short_description = 'File Download'

以下是当前输出:https://i.imgur.com/Hu2NcHJ.png

1 个答案:

答案 0 :(得分:2)

停止将文件作为单独的查询集提取:

def courses(request, slug):
    query = Course.objects.get(slug=slug)
    context = {'courses': Course.objects.filter(slug=slug),
               'lectures': query.lectures.order_by('lecture_category'),
               }
    return render(request, 'courses/courses.html', context)

然后,您可以按照从讲座到files的一对一字段。

{% for lecture in category.list %}
  <li>{{ lecture.lecture_title }}</li>
  <li>{{ lecture.content }}</li>
  {% if lecture.files %}
    <li><a href='{{ MEDIA_URL }}{{ lecture.files.files.url }}'>download</a></li>
  {% endif %}
{% endfor %}

由于它是单个文件上传的一对一字段,因此将字段命名为file而不是files会更有意义:

file = models.OneToOneField('FileUpload', on_delete=models.CASCADE, null=True, blank=True)

然后,您必须更新模板才能使用lecture.file