Django ManyToManyField ordering using through?
Oto fragment konfiguracji moich modeli:]}
class Profile(models.Model):
name = models.CharField(max_length=32)
accout = models.ManyToManyField(
'project.Account',
through='project.ProfileAccount'
)
def __unicode__(self)
return self.name
class Accounts(models.Model):
name = models.CharField(max_length=32)
type = models.CharField(max_length=32)
class Meta:
ordering = ('name',)
def __unicode__(self)
return self.name
class ProfileAccounts(models.Model):
profile = models.ForeignKey('project.Profile')
account = models.ForeignKey('project.Accounts')
number = models.PositiveIntegerField()
class Meta:
ordering = ('number',)
Następnie, gdy uzyskuję dostęp do kont, jak Mogę sortować według "numeru" w modelu profilu Pośrednika, a nie domyślnej "nazwy" w modelu kont?:
for acct_number in self.profile.accounts.all():
pass
To nie działa, ale jest sednem tego, jak chcę, aby uzyskać dostęp do tych danych:
for scanline_field in self.scanline_profile.fields.all().order_by('number'):
pass
7 answers
Właśnie przez to przechodziłam.
class Profile(models.Model):
accounts = models.ManyToManyField('project.Account',
through='project.ProfileAccount')
def get_accounts(self):
return self.accounts.order_by('link_to_profile')
class Account(models.Model):
name = models.CharField(max_length=32)
class ProfileAccount(models.Model):
profile = models.ForeignKey('project.Profile')
account = models.ForeignKey('project.Account', related_name='link_to_profile')
number = models.PositiveIntegerField()
class Meta:
ordering = ('number',)
Usunąłem pola, które były poza tematem z wyjątkiem Article.name
.
To najkrótsze rozwiązanie, jakie znalazłem, Nie wiem, czy było możliwe do wykorzystania w 2010 roku, ale na pewno jest teraz.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-02 07:55:53
Menedżer ManyToManyField pozwala wybrać / filtrować dane bezpośrednio z powiązanego modelu, bez użycia jakiegokolwiek połączenia modelu przelotowego na poziomie django...
Podobnie,
Jeśli spróbujesz:
pr = Profile.objects.get(pk=1)
pr.account.all()
Zwraca Ci wszystkie konta powiązane z tym profilem. Jak widzisz, nie istnieje bezpośrednia relacja do profilu modelu przelotowego, więc nie możesz w tym momencie użyć relacji M2M... Musisz użyć odwrotnej relacji do modelu przelotowego i filtrować wyniki...
pr = Profile.objects.get(pk=1)
pr.profileaccount_set.order_by('number')
Da ci uporządkowany queryset, ale w tym przypadku to, co masz w queryset, to obiekty profileaccount, a nie Obiekty konta... Więc musisz użyć innej relacji poziomu django, aby przejść do każdego powiązanego konta z:
pr = Profile.objects.get(pk=1)
for pacc in pr.profileaccount_set.order_by('number'):
pacc.account
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-13 12:56:54
Jest literówka w profilu (to "accout", kiedy myślę, że masz na myśli "konto"), ale co ważniejsze, masz swoje formy liczby pojedynczej/mnogiej pomieszane w modelu.
W Django praktyka polega na nazywaniu Twoich klas w liczbie pojedynczej, a twojego ManyToManyField w liczbie mnogiej. Więc:
class Profile(models.Model):
name = models.CharField(max_length=32)
accounts = models.ManyToManyField(
'Account',
through='ProfileAccount'
)
def __unicode__(self)
return self.name
class Account(models.Model):
name = models.CharField(max_length=32)
type = models.CharField(max_length=32)
class Meta:
ordering = ('name',)
def __unicode__(self)
return self.name
class ProfileAccount(models.Model):
profile = models.ForeignKey(Profile)
account = models.ForeignKey(Account)
number = models.PositiveIntegerField()
class Meta:
ordering = ('number',)
Jestem trochę zdezorientowany, co próbujesz zrobić z tym modelem, ale jeśli wprowadzisz te zmiany, to powinno zadziałać. Zakładając, że nie ma innych problemów.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-10-10 22:19:38
Dodaj powiązaną nazwę do ProfileAccounts, a następnie zmień kolejność na kontach za pomocą 'powiązana_nazwa_ _ numer'. Zwróć uwagę na dwa podkreślenia między related_name i number. Patrz poniżej:
class Accounts(models.Model):
.
.
.
class Meta:
ordering = ('profile_accounts__number',)
class ProfileAccounts(models.Model):
.
.
.
account = models.ForeignKey('project.Accounts', related_name='profile_accounts')
number = models.PositiveIntegerField()
class Meta:
ordering = ('number',)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-09 03:36:11
To mi pomogło:
Profile.objects.account.order_by('profileaccounts')
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-02 09:07:49
Najprostszym rozwiązaniem tego konkretnego problemu wydaje się być
for acct in self.profile.accounts.order_by('profileaccounts'):
pass
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-30 14:58:42
Mam to na kilku moich modelach, ale moim zdaniem (i w przeciwieństwie do wszystkich innych odpowiedzi) nie powinieneś ponownie podawać order_by
, ponieważ, cóż, jest to już określone w modelu through
. Podanie go ponownie łamie zasadę DRY (don ' t repeat yourself).
Użyłbym:
qs = profile.profileaccounts_set.all()
To daje zestaw kont ProfileAccounts powiązanych z profilem przy użyciu skonfigurowanego zamówienia. Wtedy:
for pa in qs:
print(pa.account.name)
W przypadku punktów bonusowych można również przyspieszyć cały proces poprzez użycie select_related
w zapytaniu.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-04 00:52:18