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(我不使用核心 photologues 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 并调用 Model1some_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))

郑重声明,我仍然推荐继承,但这也可以。执行这一小步骤消除了混合两个独立模型的绑定方法的混乱,并清除了数据的来源。