FieldDoesNotExist与OneToOne

时间:2016-09-11 10:28:52

标签: django one-to-one photologue

我想根据Photologue应用为用户制作图库。为了将用户的个人资料连接到photologue的模型,我想使用OneToOne。我也想......让我们说'覆盖'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的网址url(r'^photologue/', include('photologue.urls', namespace='photologue')),,因为我将应用程序集成到我自己的网址架构中)

是否可以恢复到像这样的东西

gallery = GalleryExtended.objects.filter(user=user).***(get fields from Gallery)***

并避免django.core.exceptions.FieldDoesNotExist: GalleryExtended has no field named 'date_added'以便开始使用get_absolute_url中的GalleryExtended

我知道,通过继承扩展photologue模型很容易解决,但我想知道是否可以使用OneToOne?因为在某些来源我已经读过,建议使用1to1而不是继承。

1 个答案:

答案 0 :(得分:0)

所以,我想我现在明白你想做什么。而且每一个方面都是错误的,黑客和坏的 首先 - 模型继承没有什么可担心的,事实上它恰恰相反。如果您决定不遵循OOP最重要的原则之一,那么您现在遇到的喧嚣就是一个很好的例子。诸如“我从某处读取某些东西”这样的论据无法真正转换我,我真的建议您使用继承而不是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的{​​{1}}(如果错误则更正)。
当您将some_method()参数替换为符合条件的其他模型时,可以使用hacky解决方案来实现这一点 即

self

那么如何以更加pythonic的方式编写它并仍保持1to1关系?将有问题的方法更改为带有参数的静态方法,如果需要将其作为任一模型的绑定方法调用,请使用相应的参数调用相同的静态方法。但代码说超过1000个单词:

all_method_values = []
for obj in Model2.objects.all():
    all_method_values.append(Model1.some_method(obj))

现在,除了上面显示的丑陋之外,你可以打电话而不是丑陋的黑客:

# 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])

为了记录,我仍然建议继承,但这也可以。这一小步骤消除了混合两个单独模型的绑定方法的混乱,并清除数据来自何处。