简体   繁体   English

每次使用不同的文件夹在特定根目录下的django数据库中上载文件

[英]Uploading a file in django database in a specific root with diferrent folders everytime

I´m trying to upload file into database, but when i want put the function uoload to and i want to that function store the file in a root with the data the user submit in the for, for example year, course, section, I get that information and the file they uploaded I want to store in that subfolders, the code that I´m using only store the data in the Media_root, but not in the carpets how can I do in order to store the files in the subfolder I want. 我正在尝试将文件上传到数据库中,但是当我想把函数uoload放到我希望该函数将文件存储在根目录中时,用户在for中提交的数据,例如年份,课程,部分,我得到那些信息和他们上传的文件我要存储在那个子文件夹中,我使用的代码只将数据存储在Media_root中,而不是在地毯中我怎么做才能将文件存储在子文件夹中想。 I'n my model document I store the information of the document, like the autor, the title,etc. 我是我的模型文档,我存储了文档的信息,如autor,title等。

class File(models.Model):
     titulo_file=models.ForeignKey(Document,on_delete=models.CASCADE,null=True,verbose_       name='Título de la Tesis')
     file = models.FileField(null=True,blank=True, upload_to=generate_path)

Here the function I use to upload the file, Int only works to store the file into a folder with it´s same name. 这里是我用来上传文件的函数,Int只能将文件存储到同名的文件夹中。

def generate_path(instance, filename):

      path =os.path.join(instance.file.name,filename)
      return path

In my view, after the user submit the information, I use a os.path.join , that do the path with the information submited like this: 在我看来,在用户提交信息之后,我使用了一个os.path.join ,它使用os.path.join的信息来执行路径:

year/course/section

I want to send that path to my generate_path and store in that location the file, I tried with session but it doesn't work, what can I do? 我想将该路径发送到我的generate_path并在该位置存储该文件,我尝试了会话但它不起作用,我该怎么办?

models.py models.py

class Year(models.Model):
    year_number=models.CharField(max_length=10,primary_key=True)

class Course(models.Model):
    name=models.CharField(max_length=50,primary_key=True)

class Section(models.Model):
    numberSection=models.IntegerField(null=True,blank=True)
    year = models.ForeignKey(Year, on_delete=models.CASCADE, null=True)
    course = models.ForeignKey(Course, on_delete=models.CASCADE)

thopic_documents=(
       ('CS','CS'),
       ('SE','SE'),
       ('IS','IS'),
       ('IT','IT'),
    )

class Document(models.Model):
     title=models.CharField(max_length=200,primary_key=True)
     thopic=models.CharField(max_length=50,choices=thopic_documents, default=None,null=True)

class Historial(models.Model):
      id_section=models.ForeignKey(Section,on_delete=models.CASCADE)
      title_document=models.ForeignKey(Document,on_delete=models.CASCADE,)

To get the year/course/section you need to be able to navigate from a File to a Section . 要获得年份/课程/部分,您需要能够从File导航到Section However, the many-many relationship that exists between Document and Section through Historical makes it unclear how you would do that. 然而,这之间存在多对多的关系, DocumentSection通过Historical使得它不清楚你会怎么做。 Which Historical would you choose? 你会选择哪种Historical

It may be better if File was linked directly to Historical : 如果File直接链接到Historical可能会更好:

class File(models.Model):
     titulo_file=models.ForeignKey(Historical, on_delete=models.CASCADE,null=True,verbose_name='Título de la Tesis')
     file = models.FileField(null=True,blank=True, upload_to=generate_path)

If that was the case, you could then implement your generate_path() such as: 如果是这种情况,那么您可以实现generate_path()例如:

def generate_path(instance, filename):
    section = instance.titulo_file.id_section
    year = section.year.year_number
    course = section.course.name
    return os.path.join(str(year), course, str(section.numberSection), filename)

To do the same thing with the model as it currently stands, you would have to do something like this: 要对目前的模型做同样的事情,你必须做这样的事情:

def generate_path(instance, filename):
    section = instance.titulo_file.historical_set.first().id_section
    year = section.year.year_number
    course = section.course.name
    return os.path.join(str(year), course, str(section.numberSection), filename)

That example uses historical_set.first() to get the first Historical linked the Document . 该示例使用historical_set.first()来获取链接Document的第一个Historical Maybe that would be ok, but otherwise you'd need to know which Historical to use. 也许那没关系,但是否则你需要知道要使用哪个Historical

Where a file with the same name is uploaded and you don't want to overwrite it, you could implement your own storage : 如果上传了具有相同名称的文件并且您不想覆盖它,则可以实现自己的存储

from django.core.files.storage import FileSystemStorage

class UseExistingStorage(FileSystemStorage):

    def save(self, name, content, max_length=None):
        if not self.exists(name):
            return super().save(name, content, max_length)
        return name  # Don't save when the file exists, just return the name

Then reference the UseExistingStorage from your File model. 然后从File模型中引用UseExistingStorage

file = models.FileField(null=True,blank=True, upload_to=generate_path, storage=UseExistingStorage())

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM