Python Django createview创建没有外键的额外实例
我正在使用Django createview在拍卖网站中创建出价项目。createview将创建新对象,但它会创建一个没有相应外键的额外对象实例。我使用@staticmethod来确定提交的出价是否确实是相关列表中创建的最高出价。如果你能指出我做错了什么,请提前谢谢你 models.pyPython Django createview创建没有外键的额外实例,python,django,django-models,django-forms,Python,Django,Django Models,Django Forms,我正在使用Django createview在拍卖网站中创建出价项目。createview将创建新对象,但它会创建一个没有相应外键的额外对象实例。我使用@staticmethod来确定提交的出价是否确实是相关列表中创建的最高出价。如果你能指出我做错了什么,请提前谢谢你 models.py class Bid(TimeStampMixin): """model representing bid obj""" auction
class Bid(TimeStampMixin):
"""model representing bid obj"""
auction = models.ForeignKey(
Listing,
on_delete=models.SET_NULL,
related_name='offer',
null=True)
bidder = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.SET_NULL,
null=True,
related_name='bid_user')
amount = models.PositiveIntegerField()
objects = BidQuerySet.as_manager()
def __str__(self):
return f"{self.amount} in Listing No: {self.auction.id}"
class Meta:
ordering = ['amount']
@staticmethod
def high_bid(auction, bidder, bid_amount):
"""util method to ascertain highest bid in auction then create in related auction obj
:param auction---listing being bid on, bid__auction
:param bidder---user bidding
:param amount--- current highest bid
"""
###error checks, is auction running? is current bid less than start bid? etc
if bid_amount < auction.start_bid:
return
if (auction.highest_offer and bid_amount < auction.highest_offer.amount):
return
if bidder.id is auction.user.id:
raise PermissionDenied
##after checks create highest bid object in listing model
new_high_bid = Bid.objects.create(
auction= auction,
bidder = bidder,
amount = bid_amount
)
auction.highest_offer = new_high_bid
auction.save()
class Listing(TimeStampMixin):
user = models.ForeignKey(
User,
on_delete=models.CASCADE,
related_name="seller")
product = models.ForeignKey(
Product,
on_delete=models.CASCADE,
related_name="item")
start_bid = models.PositiveIntegerField(
default=0)
date_end = models.DateTimeField()
duration = models.ForeignKey(
Duration,
on_delete=models.SET_NULL,
null=True,
blank=True,
)
###static method in Bid model creates this
highest_offer = models.ForeignKey(
'Bid',
related_name = 'highest_bid',
on_delete = models.SET_NULL,
null = True,
blank = True,
)
def __str__(self):
return f"Listing for {self.product} by {self.user}."
forms.py
class BidForm(forms.ModelForm):
class Meta:
model = Bid
fields = [
'amount',
]
widgets = {
'amount' : forms.NumberInput(attrs={'class' : 'form-control'}),
}
def __init__(self, *args, **kwargs):
"""override __init__ pop related auction from kwargs"""
self.auction = kwargs.pop("auction", None)
##call super with related obj
super().__init__(*args, **kwargs)
##clean data/validate, ensuring bid is larger than highest bid and starting bid
def clean_amount(self):
amount = self.cleaned_data["amount"]
##check if less than starting bid
if self.auction.start_bid > amount:
raise ValidationError(_('Bid is less than starting bid'))
if (self.auction.highest_offer.amount >= amount):
raise ValidationError(_('Bid is less than current highest bid'))
return amount
显示不带外键的额外bid对象的DB表
删除
返回super().form\u valid(form)
行
这行代码将从继承的类调用form_valid,该类将保存对象-这是创建的没有外键的额外对象
相反,您会希望返回某种http响应(例如,render\u to\u响应、重定向等)。非常有效,谢谢。只是想澄清一下super().form\u valid(form)会调用form\u valid两次,创建额外的对象吗?抱歉,我是python中oop的新手,我正在尝试更好地理解。我可以尝试解释:您的视图继承自CreateView,CreateView中有一个form\u有效函数将运行
form.save()
,这将基于表单中的值创建对象-这是CreateView的默认行为。您最终创建了两个对象,因为您在表单中调用Bid.high\u Bid\u valid(最终创建了一个Bid对象),然后通过调用创建另一个Bid对象的super.form\u valid(form)
调用默认的CreateView行为。
class BidForm(forms.ModelForm):
class Meta:
model = Bid
fields = [
'amount',
]
widgets = {
'amount' : forms.NumberInput(attrs={'class' : 'form-control'}),
}
def __init__(self, *args, **kwargs):
"""override __init__ pop related auction from kwargs"""
self.auction = kwargs.pop("auction", None)
##call super with related obj
super().__init__(*args, **kwargs)
##clean data/validate, ensuring bid is larger than highest bid and starting bid
def clean_amount(self):
amount = self.cleaned_data["amount"]
##check if less than starting bid
if self.auction.start_bid > amount:
raise ValidationError(_('Bid is less than starting bid'))
if (self.auction.highest_offer.amount >= amount):
raise ValidationError(_('Bid is less than current highest bid'))
return amount