Python Django-通过OneToOneField访问属性
我对Django很陌生,我想知道我是否可以就我面临的问题寻求一些帮助。我试图在Django中构建一组模型,其结构如下:Python Django-通过OneToOneField访问属性,python,django,django-models,Python,Django,Django Models,我对Django很陌生,我想知道我是否可以就我面临的问题寻求一些帮助。我试图在Django中构建一组模型,其结构如下: app\u用户描述我正在构建的应用程序的用户。 app\u作业描述了用户希望在应用程序上运行的作业,以及若干相关输入(upload1,upload2,upload3)。一个用户可以运行多个作业;因此,我使用作业和用户之间的多对一(ForeignKey)关系。创建app_作业时,我希望将其关联文件上载到由关联用户的用户名和num_作业属性确定的目录,如图所示 运行python m
app\u用户
描述我正在构建的应用程序的用户。
app\u作业
描述了用户希望在应用程序上运行的作业,以及若干相关输入(upload1
,upload2
,upload3
)。一个用户可以运行多个作业;因此,我使用作业和用户之间的多对一(ForeignKey
)关系。创建app_作业
时,我希望将其关联文件上载到由关联用户的用户名
和num_作业
属性确定的目录,如图所示
运行python manage.py makemigrations
时,我收到以下错误:AttributeError:“ForeignKey”对象没有属性“user”
。这就引出了一个问题:如何从app\u作业
类中访问底层app\u用户的信息
谢谢你的帮助
# 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) )
基于这样的情况,应该可以:
# 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)
好的,这里有几个问题。但没有一点教育不能解决的问题
- 模型应该用骆驼套,这样更容易阅读,通常是一种很好的做法
- 您不需要在模型前面加上
app
前缀,没有这个前缀,它更清晰、更容易阅读
反正
您的app\u作业
model外键应指向User
而不是app\u用户
模型。通过这样做,您仍然可以访问app\u用户
数据
您还需要修改upload_to
属性。虽然uploads_to
可以是一个字符串值,但无法按照您当前的方式进行计算。查看详细信息(无耻的插件,我最近重新编写了这部分文档)
相反,您需要执行以下操作:
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)
正如你所知道的,有几个问题。但这很好学:)
首先,类名应以大写字母开头,并使用“camelCase”,
在您的例子中,“AppUser”和“AppJob”。就我个人而言,我不会用“App”作为后缀,而是用“MyUser”和“Job”
“ForeignKey”对象没有属性“user”时出现的错误是因为在“app_作业”模型中,您有一个ForeignKey to app_user,这可以创建两个模型之间的关系,但在文件字段中,您使用的是与模型“app_user”同名的“ForeignKey”对象那个ForeignKey实例并没有一个名为“user”的属性,你们明白了吗
那些家伙给你的关于“上传到”的信息是正确的:)。
你可以在网站上获得更多信息
谢谢问题不在于访问相关数据,而在于尝试访问类定义中的实例属性数据。1:类名应为CAMEL CASE。第二:@DMunoz类AppJob
中没有名为user的属性。第三:upload\u to
可以是可调用的,但您拥有的是表达式,而不是可调用的。第四点:确保在创建用户时创建了一个app\u用户
实例。可以实现(例如,用户上的post\u save
)
# 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)