TypeError at /listing: save() missing 1 required positional argument: 'self'

Я пытаюсь сделать сайт аукциона, и у меня возникла проблема с изменением ставки в модели Bids для определенного объекта Auctionlisting при отправке данных POST.

class Bids(models.Model):
    minimum_bid = models.DecimalField(max_digits=8, decimal_places=2, null=False)
    allbids = []
    bid = models.DecimalField(max_digits=8, decimal_places=2, null=True, blank=True)

    allbids.append(bid)
    numBids = len(allbids)


    def __str__(self):
        if self.bid == None:
            return f"Minimum Bid: ${self.minimum_bid}" 
        else:
            return f"Highest Bid: ${self.bid}"
    

    def save(self, userbid, object):
        item = self.objects.get(pk=object)
        item.bid = userbid
        item.save()
        

Вот моя модель AuctionListing:

class AuctionListing(models.Model):

    title = models.CharField(max_length=30)
    description = models.CharField(max_length=137)
    category = models.CharField(max_length=10, choices=Category.CHOICES, default="Men")
    image = models.ImageField(upload_to="media")
    bid = models.OneToOneField(Bids, on_delete=models.CASCADE, null=True)

    def __str__(self):
        return f"{self.category}: {self.title}"
        

Вот как я представляю данные в моих представлениях:

if request.method == "POST":
    if "userbid" in request.POST:
        try:
            userbid = AuctionListing.objects.get(pk = request.GET.get("listing"))
            userbid.bid = Bids.save(userbid=1000,object=object)
            userbid.save()

        except IntegrityError:
            pass

Моделирование довольно странное. Объект AuctionListing ссылается на модель Bids, но в этом нет особого смысла. В случае, если каждый AcutionListing имеет объект Bids и наоборот, более разумно просто добавить данные в сам AuctionListing.

Кроме того, вы не храните индивидуальные ставки. Если позже аукцион будет закрыт, как вы узнаете, кто сделал самую высокую ставку? Ваша модель Bids также создает список и добавляет к нему поле bid , но это единственный элемент, который он будет содержать. Логика в классе оценивается только один раз: когда класс построен, поэтому с момента интерпретации класса bid и numBids уже не имеют особого смысла.

В Bids также содержится поле minimum_bid, но это информация, связанная с объектом, на который люди делают ставку, а не сама ставка.

Более разумное моделирование заключается в том, что у вас есть AuctionListing для представления объектов, на которые можно делать ставки. На AuctionListing может быть несколько Bid, и тогда можно определить наименьшую ставку путем аннотирования или запросов. В этом случае две модели определяются следующим образом:

class AuctionListing(models.Model):
    title = models.CharField(max_length=30)
    description = models.CharField(max_length=137)
    category = models.CharField(max_length=10, choices=Category.CHOICES, default='Men')
    image = models.ImageField(upload_to='media')
    minimum_bid = models.DecimalField(max_digits=8, decimal_places=2)

    def __str__(self):
        return f'{self.category}: {self.title}'

    def get_largest_bit(self):
        return self.bids.order_by('-bid').first()

Тогда вы можете определить модель Bid с ForeignKey к AuctionList: предмет, на который люди могут делать ставки:

class Bid(models.Model):
    item = models.ForeignKey(
        AuctionListing,
        on_delete=models.CASCADE,
        related_name='bids'
    )
    bid = models.DecimalField(max_digits=8, decimal_places=2)

В вашем представлении, вы можете сделать ставку на AuctionList товар с первичным ключом pk с:

from django.shortcuts import get_object_or_404

def make_bid(request, pk):
    item = get_object_or_404(AuctionList, pk=pk)
    if request.method == 'POST':
        bid_value = request.POST['bid']  # retrieve the bid value from somewhere
        if bid_value < item.minimum_bid:
            # do something, report an error
            # …
        else:
            Bid.objects.create(item_id=pk, bid=bid_value)
            return redirect('name-of-some-view')
    else:
        # …
    # …
Вернуться на верх