FieldDoesNotExist 与 OneToOne
FieldDoesNotExist with OneToOne
我想基于 Photologue
应用程序为用户制作图库。为了将用户的个人资料连接到 photologue 的模型,我想使用 OneToOne
。我也想...让我们说 'override' photologue 的 get_absolute_url
,它被模板使用。
# models
from photologue.models import Gallery
from profiles.models import UserProfile
class GalleryExtended(models.Model):
gallery = models.OneToOneField(Gallery)
user = models.ForeignKey(UserProfile, verbose_name=_('user'), on_delete=models.CASCADE)
def get_absolute_url(self):
return reverse('profiles_user:profiles_gallery-details', args=[self.user.user_url, self.gallery.slug])
# views
from photologue.views import Gallery
from profiles.models import UserProfile
from .models import GalleryExtended, PhotoExtended
def get_user_gallery_queryset(self):
user = get_object_or_404(UserProfile, user_url=self.kwargs['user_url'])
gallery = Gallery.objects.filter(galleryextended__user=user)
return gallery
class ProfileGalleryDateView(object):
date_field = 'date_added'
allow_empty = True
get_queryset = get_user_gallery_queryset
# site.com/username/gallery (shows photos + images with a filter by year)
class ProfileGalleryPhotoArchiveIndexView(ProfileGalleryDateView, ArchiveIndexView):
template_name = 'galleries/gallery_n_photo_archive.html'
所以在我看来
gallery = Gallery.objects.filter(galleryextended__user=user)
模板开始使用 Photologue 的 get_absolute_url
(我不使用核心 photologue
s url url(r'^photologue/', include('photologue.urls', namespace='photologue')),
因为我将应用程序集成到我自己的 url架构)
是否有可能恢复到这样的状态
gallery = GalleryExtended.objects.filter(user=user).***(get fields from Gallery)***
并避免 django.core.exceptions.FieldDoesNotExist: GalleryExtended has no field named 'date_added'
以便从 GalleryExtended
?
开始使用 get_absolute_url
我知道,通过继承扩展photologue
的模型很容易解决,但我想知道是否可以使用OneToOne?因为在我读过的一些资料中,建议使用 1to1 而不是继承。
所以,我想我现在明白你想做什么了。它在各个方面都是错误的、老套的和糟糕的。
首先——模型继承没什么可怕的,事实上恰恰相反。如果您决定不遵循 OOP 最重要的原则之一,您现在正在经历的喧嚣就是一个很好的例子。 "I read something from somewhere" 之类的论点不能真正改变我,我真的建议你使用继承而不是 1to1 关系。更不用说每次需要在同一个地方使用对象时,使用 1to1 关系而不是继承也会创建额外的数据库查询。
尽管不建议继续进行此设置,但我可以为您提供一些可能的版本来实现类似于您想要的东西。它并不完美,因为它不应该以这种方式使用。
如果我们现在在同一页面上,那么您的结构如下:
class Model1(models.Model):
name = models.CharField(max_length=128)
state = models.CharField(max_length=128)
def some_method(self):
return self.name
class Model2(models.Model):
first = models.OneToOneField(Model1, related_name='second')
name = models.CharField(max_length=128)
def some_method(self):
return self.name + '2345678'
您想查询出所有的 Model2
并调用 Model1
的 some_method()
(错误则更正)。
当您将 self
参数替换为符合条件的另一个模型时,这可以通过一个 hacky 解决方案来实现。
IE。
all_method_values = []
for obj in Model2.objects.all():
all_method_values.append(Model1.some_method(obj))
那么如何以更 pythonic 的方式编写它并仍然保持 1to1 关系?将有问题的方法更改为带有参数的静态方法,如果您需要将其作为任一模型的绑定方法调用,请让它们使用各自的参数调用相同的静态方法。但是代码说了 1000 多个字:
# In the model
def get_absolute_url(self):
return GalleryExtended.get_gallery_url(self.user.user_url, self.gallery.slug)
@staticmethod
def get_gallery_url(user_url, slug):
return reverse('profiles_user:profiles_gallery-details', args=[self.user.user_url, self.gallery.slug])
现在,您可以不用丑陋的 hacking 调用,而不是上面显示的丑陋:
all_method_values = []
for obj in Model2.objects.all():
all_method_values.append(Model1.get_gallery_url(obj.user.user_url, obj.gallery.slug))
郑重声明,我仍然推荐继承,但这也可以。执行这一小步骤消除了混合两个独立模型的绑定方法的混乱,并清除了数据的来源。
我想基于 Photologue
应用程序为用户制作图库。为了将用户的个人资料连接到 photologue 的模型,我想使用 OneToOne
。我也想...让我们说 'override' photologue 的 get_absolute_url
,它被模板使用。
# models
from photologue.models import Gallery
from profiles.models import UserProfile
class GalleryExtended(models.Model):
gallery = models.OneToOneField(Gallery)
user = models.ForeignKey(UserProfile, verbose_name=_('user'), on_delete=models.CASCADE)
def get_absolute_url(self):
return reverse('profiles_user:profiles_gallery-details', args=[self.user.user_url, self.gallery.slug])
# views
from photologue.views import Gallery
from profiles.models import UserProfile
from .models import GalleryExtended, PhotoExtended
def get_user_gallery_queryset(self):
user = get_object_or_404(UserProfile, user_url=self.kwargs['user_url'])
gallery = Gallery.objects.filter(galleryextended__user=user)
return gallery
class ProfileGalleryDateView(object):
date_field = 'date_added'
allow_empty = True
get_queryset = get_user_gallery_queryset
# site.com/username/gallery (shows photos + images with a filter by year)
class ProfileGalleryPhotoArchiveIndexView(ProfileGalleryDateView, ArchiveIndexView):
template_name = 'galleries/gallery_n_photo_archive.html'
所以在我看来
gallery = Gallery.objects.filter(galleryextended__user=user)
模板开始使用 Photologue 的 get_absolute_url
(我不使用核心 photologue
s url url(r'^photologue/', include('photologue.urls', namespace='photologue')),
因为我将应用程序集成到我自己的 url架构)
是否有可能恢复到这样的状态
gallery = GalleryExtended.objects.filter(user=user).***(get fields from Gallery)***
并避免 django.core.exceptions.FieldDoesNotExist: GalleryExtended has no field named 'date_added'
以便从 GalleryExtended
?
get_absolute_url
我知道,通过继承扩展photologue
的模型很容易解决,但我想知道是否可以使用OneToOne?因为在我读过的一些资料中,建议使用 1to1 而不是继承。
所以,我想我现在明白你想做什么了。它在各个方面都是错误的、老套的和糟糕的。
首先——模型继承没什么可怕的,事实上恰恰相反。如果您决定不遵循 OOP 最重要的原则之一,您现在正在经历的喧嚣就是一个很好的例子。 "I read something from somewhere" 之类的论点不能真正改变我,我真的建议你使用继承而不是 1to1 关系。更不用说每次需要在同一个地方使用对象时,使用 1to1 关系而不是继承也会创建额外的数据库查询。
尽管不建议继续进行此设置,但我可以为您提供一些可能的版本来实现类似于您想要的东西。它并不完美,因为它不应该以这种方式使用。
如果我们现在在同一页面上,那么您的结构如下:
class Model1(models.Model):
name = models.CharField(max_length=128)
state = models.CharField(max_length=128)
def some_method(self):
return self.name
class Model2(models.Model):
first = models.OneToOneField(Model1, related_name='second')
name = models.CharField(max_length=128)
def some_method(self):
return self.name + '2345678'
您想查询出所有的 Model2
并调用 Model1
的 some_method()
(错误则更正)。
当您将 self
参数替换为符合条件的另一个模型时,这可以通过一个 hacky 解决方案来实现。
IE。
all_method_values = []
for obj in Model2.objects.all():
all_method_values.append(Model1.some_method(obj))
那么如何以更 pythonic 的方式编写它并仍然保持 1to1 关系?将有问题的方法更改为带有参数的静态方法,如果您需要将其作为任一模型的绑定方法调用,请让它们使用各自的参数调用相同的静态方法。但是代码说了 1000 多个字:
# In the model
def get_absolute_url(self):
return GalleryExtended.get_gallery_url(self.user.user_url, self.gallery.slug)
@staticmethod
def get_gallery_url(user_url, slug):
return reverse('profiles_user:profiles_gallery-details', args=[self.user.user_url, self.gallery.slug])
现在,您可以不用丑陋的 hacking 调用,而不是上面显示的丑陋:
all_method_values = []
for obj in Model2.objects.all():
all_method_values.append(Model1.get_gallery_url(obj.user.user_url, obj.gallery.slug))
郑重声明,我仍然推荐继承,但这也可以。执行这一小步骤消除了混合两个独立模型的绑定方法的混乱,并清除了数据的来源。