我现在对这个问题感到困惑了一段时间。它是这样的:我有一个带讲座的模型。我希望每个讲座能够上传多个文件,所以我创建了一个具有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
答案 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
。