Mam użytkownikom dzielić modelu coś jak poniżej:Django zwyczaj unikalny razem ograniczenie
class Share(models.Model):
sharer = models.ForeignKey(User, verbose_name=_("Sharer"), related_name='sharer')
receiver = models.ForeignKey(User, verbose_name=_("Receiver"), related_name='receiver')
class Meta:
unique_together = (("sharer", "receiver"), ("receiver", "sharer"))
chcę zapisać pojedynczy obiekt do współdzielenia (S) i odbiornika (R) (kolejność nie matters lub RS SR). ale powyżej unique_together nie spełni tego; Załóżmy, że R-S znajduje się w bazie danych, a następnie, jeśli zapiszę S-R, nie otrzymam walidacji. W tym celu napisałem niestandardową, unikatową walidację modelu Share.
def validate_unique(
self, *args, **kwargs):
super(Share, self).validate_unique(*args, **kwargs)
if self.__class__.objects.filter(Q(sharer=self.receiver, receiver=self.sharer)).exists():
raise ValidationError(
{
NON_FIELD_ERRORS:
('Share with same sharer and receiver already exists.',)
}
)
def save(self, *args, **kwargs):
# custom unique validate
self.validate_unique()
super(Share, self).save(*args, **kwargs)
Ta metoda działa prawidłowo podczas normalnego użytkowania.
Problem: mam algorytm dopasowywania który dostaje akcji i żądań odbiornika oraz zapisanie obiekt Poleć (albo S-R lub R-S), a następnie wysłać do nich odpowiedzi (obiekt zakładowego) niemal w tym samym czasie. Podczas sprawdzania duplikacji z zapytaniem (brak poziomu bazy danych) zajmuje to trochę czasu, więc na koniec mam 2 obiekty S-R i R-S.
Potrzebuję rozwiązania tego problemu, że dla sharer S i odbiornika R I można zapisać tylko obiekt pojedynczego udziału, albo S-R lub R-S jeszcze uzyskać błąd sprawdzania poprawności (jak IntegrityError z databse).
Django = 1,4, Database = Postgresql
Dziękuję za odpowiedź. Miałem 2 rozwiązania. Jeden do obsłużenia go przez unikalny numer żądania (podczas dopasowywania w inkrementowanym identyfikatorze Redis) i zapisania pierwszego udziału obj z niższym żądaniem #, a następnie oczekiwania i uzyskania share_obj dla wyższego żądania #. ale rozwiązałem go za pomocą drugiego rozwiązania (opisanego przez ciebie), aby posortować listę nazw użytkowników zarówno sharer, jak i receive, w ten sposób otrzymam zawsze ten sam wzorzec sharer i receiver. Zapiszę żądanie i jeśli otrzymam IntegrityError przez postgresql, wycofam transakcję i zabezpieczyłem już zapisany obiekt S-R. :) –