我对Django很新,我想知道我是否可以就我面临的问题寻求帮助。我试图在Django中构建一组模型,其结构如下:
app_user
描述了我正在构建的应用程序的用户。
app_job
描述了用户想要在应用上运行的作业,其中包含多个相关输入(upload1
,upload2
,upload3
)。用户可以运行许多工作;因此,我使用作业和用户之间的多对一(ForeignKey
)关系。创建app_job
后,我希望将其关联文件上传到由关联用户的username
和num_jobs
属性确定的目录,如图所示。
当我运行python manage.py makemigrations
时,收到以下错误:AttributeError: 'ForeignKey' object has no attribute 'user'
。这引出了一个问题,如何从app_user
类访问基础app_job
的信息?
感谢您的帮助。
# models.py
from django.db import models
from django.contrib.auth.models import User
from django.forms import ModelForm
class app_user(models.Model):
user = models.OneToOneField(User)
num_jobs = models.IntegerField(default = 0)
def __unicode__(self):
return self.user.get_username()
class app_job(models.Model):
app_user = models.ForeignKey(app_user)
upload1 = models.FileField(upload_to = app_user.user.get_username() + "/" + str(app_user.num_jobs) , blank = True, null = True)
upload2 = models.FileField(upload_to = app_user.user.get_username() + "/" + str(app_user.num_jobs))
upload3 = models.FileField(upload_to = app_user.user.get_username() + "/" + str(app_user.num_jobs) )
答案 0 :(得分:4)
好的,这里有几个问题。但是没有什么教育无法解决。
app_
更清晰,更容易阅读。反正
您app_job
模型的ForeignKey应该是User
而不是app_user
模型。通过这样做,您仍然可以访问app_user
数据。
您还需要修改upload_to
属性。虽然uploads_to
可以是字符串值,但它无法按照您当前的方式进行评估。查看django filefield documentation了解详细信息(无耻插件,我最近重写了这部分文档)。
相反,您需要执行以下操作:
def user_directory_path(instance, filename):
# file will be uploaded to MEDIA_ROOT/user_<id>/<filename>
return 'user_{0}/{1}'.format(instance.user.id, filename)
class app_job(models.Model):
app_user = models.ForeignKey(User)
upload1 = models.FileField(upload_to=user_directory_path , blank = True, null = True)
upload2 = models.FileField(upload_to=user_directory_path
upload3 = models.FileField(upload_to=user_directory_path, blank=True, null=True)
这样做upload_to
调用函数user_directory_path
来生成文件路径。
通过以上内容,你应该有:
# models.py
from django.db import models
from django.contrib.auth.models import User
from django.forms import ModelForm
class UserProfile(models.Model):
"""
In settings.py you will want to add a link to AUTH_USER_PROFILE
See https://docs.djangoproject.com/en/1.8/topics/auth/customizing/#extending-the-existing-user-model
"""
user = models.OneToOneField(User)
num_jobs = models.IntegerField(default=0)
def __unicode__(self):
return self.user.get_username()
def upload_dir(instance, filename):
return instance.user.get_username() + "/" + str(instance.user.num_jobs)
class Job(models.Model):
user = models.ForeignKey(User)
upload1 = models.FileField(upload_to=upload_dir, blank = True, null = True)
upload2 = models.FileField(upload_to=upload_dir, blank=True, null=True)
upload3 = models.FileField(upload_to=upload_dir, blank=True, null=True)
答案 1 :(得分:1)
基于this answer to a similar question这样的事情应该有效:
# models.py
from django.db import models
from django.contrib.auth.models import User
class app_user(models.Model):
user = models.OneToOneField(User)
num_jobs = models.IntegerField(default = 0)
def __unicode__(self):
return self.user.get_username()
def content_file_name(instance, filename):
return '/'.join([instance.app_user.user.get_username(), str(instance.app_user.num_jobs), filename])
class app_job(models.Model):
app_user = models.ForeignKey(app_user)
upload1 = models.FileField(upload_to = content_file_name , blank = True, null = True)
upload2 = models.FileField(upload_to = content_file_name)
upload3 = models.FileField(upload_to = content_file_name)
答案 2 :(得分:0)
正如您所知,有几个问题。但它的好处是:)。
首先,班级名称应以大写字母开头,并使用&#34; camelCase&#34;, 在你的情况下,&#34; AppUser&#34;和#34; AppJob&#34;。我个人不会使用&#34; App&#34;作为后缀,我只会使用&#34; MyUser&#34;和&#34;工作&#34;。
你得到的错误&#34;&#39; ForeignKey&#39;对象没有属性&#39; user&#34;是因为在你的&#34; app_job&#34;模型你有一个ForeignKey到app_user,这是可以的,它创建了两个模型之间的关系,但然后在FileField你正在使用&#34; foreignkey&#34;与您的模型同名的对象&#34; app_user&#34;而且ForeignKey实例没有名为&#34; user&#34;的属性,你知道吗?
这些人给你的信息与&#34; upload_to&#34;是正确的 :)。 您可以在Django docs
中获取更多信息由于