2016-09-11 6 views
0

Я хочу сделать галерею пользователей по Photologue. Чтобы подключить профили пользователей к моделям фотолога, я хочу использовать OneToOne. Также я хочу ... скажем, «переопределить» фотолога get_absolute_url, который используется шаблонами.FieldDoesNotExist with OneToOne

# 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 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', чтобы начать использовать get_absolute_url от GalleryExtended?

Я знаю, это легко решить, расширив модель photologue через наследование, но я хочу знать, можно ли использовать OneToOne? потому что в некоторых источниках, которые я прочитал, рекомендуется использовать 1to1 вместо наследования.

+0

Я не думаю, что вы либо понимаете свою проблему, либо очень четко объясняете нам. Исключение 'FieldDoesNotExist' не имеет ничего общего с дилеммой модели OneToOne. Вместо этого где-то вы запрашиваете значение поля 'date_added' из' GalleryExtended', но поскольку этого не существует, вы получаете сообщение об ошибке. Расскажите, пожалуйста, что вы хотите достичь с этим ответом, и мы сделаем все возможное. – makaveli

+0

@ makaveli. У собственной модели 'photologue' Gallery' есть несколько полей (включая 'date_added'). Если я делаю QuerySet с использованием модели «Галерея», 'get_absolute_url' используется из модели« Галерея ». Я хочу использовать 'get_absolute_url' из модели GalleryExtended, но у этой модели нет всех полей, которые требуется коду. Мой вопрос: возможно ли получить поля (или, может быть, instanse, я точно не знаю) модели «Галерея» со стороны модели GalleryExtended? Перефразируемый вопрос может быть: можно ли с OneToOne получить что-то вроде наследования, когда один экземпляр имеет все функции обеих моделей? – TitanFighter

+0

Ну да, если я правильно вас понимаю, вы просто просите «GalleryExtended.objects.filter (user = user) .first(). Gallery. <Имя поля/метода>», то есть 'GalleryExtended.objects.filter (пользователь = пользователь) .first(). gallery.title'. Правильно я или нет? – makaveli

ответ

0

Итак, я думаю, теперь я понимаю, что вы хотите сделать. И это неправильно, хаки и плохо во всех отношениях.
Прежде всего - наследование модели нечего бояться, на самом деле все наоборот. Суета, которую вы испытываете сейчас, является прекрасным примером того, что находится в магазине, если вы решите не следовать одному из самых важных принципов ООП. Аргументы, такие как «Я что-то читал откуда-то», не могут меня преобразовать, и я действительно рекомендую вам использовать наследование вместо отношений 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 «s some_method() на них (правильно).
Это может быть достигнуто с помощью взломанного решения при замене аргумента self другой моделью, которая соответствует критериям.
I.e.

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

Итак, как написать это более питоническим способом и сохранить отношение 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]) 

Теперь, вместо того, чтобы уродство было показано выше, вы можете позвонить без уродливого хакерства:

all_method_values = [] 
for obj in Model2.objects.all(): 
    all_method_values.append(Model1.get_gallery_url(obj.user.user_url, obj.gallery.slug)) 

Для записи, я все же рекомендую наследство, но это работает хорошо.Выполнение этого небольшого шага устраняет путаницу смешивания двух связанных методов отдельных моделей и очищает данные, откуда поступают данные.

+0

авторы «двух совков джанго» и создатель «django-photologue» в своих документах говорят, что наследование плохое и 1to1 лучше :) – TitanFighter

+0

@TitanFighter Можете ли вы дать мне ссылку или цитату? Конечно, они не могут означать, что для всех случаев, и мне интересно, в каких случаях это может быть правдой. – makaveli

+0

из 2 совков - «любой ценой, каждый должен избегать наследования нескольких таблиц, поскольку он добавляет как путаницу, так и существенные накладные расходы. Вместо наследования нескольких таблиц используйте явные OneToOneFields и ForeignKeys между моделями, чтобы вы могли контролировать, когда пройдут соединения». - моя вина. Говорят о 'multi'-table. Поскольку одна таблица не multi, это okey. – TitanFighter

 Смежные вопросы

  • Нет связанных вопросов^_^