Есть ли способ создать функцию on_delete, которая использует информацию из конкретной модели, содержащей внешний ключ в django?
Я решаю одну из задач в веб-курсе cs50 и создал модель для листинга на сайте аукциона. Для того, чтобы избежать итераций по всем ставкам на листинг, каждый листинг имеет внешний ключ 'current_bid', который указывает на последнюю ставку. Однако если ставка будет удалена, я хочу иметь возможность установить текущую ставку как ставку, которая была сделана до нее.
Я попробовал несколько подходов, но тот, который был ближе всего к работе, это создание функции, локальной для класса модели, которая получает последнюю ставку, и пытался заставить ее работать, заставляя on_delete вызывать set(last_bid).
def last_bid(self):
bids = self.bids
last = None
for bid in bids:
if last is None:
last = bid
elif bid > last:
last = bid
return last
current_bid = models.ForeignKey('Bid', null=True, blank=True, on_delete=SET(last_bid),
related_name="running_bids")
Не работает, потому что вызов last_bid таким образом не дает ему необходимого параметра 'self'. Неужели нет способа получить ссылку на конкретное объявление, когда ставка, которую оно держит, будет удалена?
По-моему, немного тяжеловато для CS50. Однако вы можете взять исходный код Django для одной из функций удаления модели и перепрофилировать его для своих нужд, например, код models.CASCADE
выглядит так:
def CASCADE(collector, field, sub_objs, using):
collector.collect(
sub_objs,
source=field.remote_field.model,
source_attr=field.name,
nullable=field.null,
fail_on_restricted=False,
)
if field.null and not connections[using].features.can_defer_constraint_checks:
collector.add_field_update(field, None, sub_objs)
Я полагаю, что sub_objs
- это именно то, к чему вы хотите иметь доступ, чтобы вы могли перераспределить их, вы можете сделать что-то вроде этого:
def REALLOCATE_BID(collector, field, sub_objs, using):
bid = Bid.objects.get(... # get the bid somehow
sub_objs.update(current_bid=bid)
это не ответ на ваш вопрос, но это решит вашу проблему, потому что я считаю, что вы смотрите не в ту сторону
у вас есть модели, Листинг и Предложение
class Listing(models.Model):
title = models.CharField(max_length=20)
#... etc
class Bid(models.Model):
bid = models.IntegerField(default=0)
user = models.ForeignKey(User, on_delete=models.CASCADE)
listing = models.ForeignKey(Listing, on_delete=models.CASCADE)
вам не нужно приписывать current bid
как константу, current bid
это наибольший bid
, который приписан к listing
например:
def my_listing_page(request):
listing_obj = Listing.objects.get(title = "my_listing")
biggest_bid = Bid.objects.filter(listing=listing_obj).order_by("bid").first()
В данном сценарии эта функция всегда будет выводить biggest_bid
данного листинга, и если он когда-нибудь будет удален, то следующий за ним станет biggest or current
p.s я закончил этот курс вот как я знаю ваши модели