Есть ли способ создать функцию 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 я закончил этот курс вот как я знаю ваши модели

Вернуться на верх