I am getting this error when adding a pair.
Cannot assign "'1'": "Pair.exchange" must be a "Exchange" instance.
models.py:
class Exchange(models.Model):
name = models.CharField(max_length=25)
def __str__(self) -> str:
return f'{self.name}'
class Pair(models.Model):
symbol = models.CharField(max_length=20)
ask = models.FloatField()
bid = models.FloatField()
exchange = models.ForeignKey(Exchange, on_delete=models.PROTECT)
created = models.DateTimeField()
def __str__(self) -> str:
return f'ID: {self.id} Symbol: {self.symbol} Ask: {self.ask} Bid: {self.bid} Exchange: {self.exchange}'
views.py:
def show_pair(request):
pairs = Pair.objects.all()
br = [str(pair) '<br>' for pair in pairs]
return HttpResponse(br)
def add_pair(request, symbol, ask, bid, exchange):
pair = Pair.objects.create(symbol=symbol, ask=ask, bid=bid, exchange=exchange)
return HttpResponsePermanentRedirect('/pair/')
urls.py:
path('pair/add/<symbol>/<ask>/<bid>/<exchange>/', views.add_pair)
I'm trying to add pairs via a link, but I get this error, what could be the problem?
CodePudding user response:
As the error states you can not just pass the id of the "Exchange" model, but you must pass an instance of the model.
Option 1: Fetch the model instance and pass it
def add_pair(request, symbol, ask, bid, exchange):
exchange_obj = Exchange.objects.get(id=exchange)
pair = Pair.objects.create(symbol=symbol, ask=ask, bid=bid, exchange=exchange_obj)
return HttpResponsePermanentRedirect('/pair/')
Option 2: When you create a ForeignKey
field on your model django will actually create a database column called exchange_id
, so you can also use that to create you "Pair".
def add_pair(request, symbol, ask, bid, exchange):
pair = Pair.objects.create(symbol=symbol, ask=ask, bid=bid, exchange_id=exchange)
return HttpResponsePermanentRedirect('/pair/')
As a bonus you might want to add some validation that the exchange id you are receiving is actually the correct one. You can use django's get_object_or_404
for this for example.
def add_pair(request, symbol, ask, bid, exchange):
exchange_obj = get_object_or_404(Exchange.objects.all(), id=exchange)
pair = Pair.objects.create(symbol=symbol, ask=ask, bid=bid, exchange=exchange_obj)
return HttpResponsePermanentRedirect('/pair/')
CodePudding user response:
As the error says, you need to provide an Exchange
object, but it is more efficient to pass the exhange_id
directly:
from django.shortcuts import redirect
from django.views.decorators.http import require_http_methods
@require_POST
def add_pair(request, symbol, ask, bid, exchange):
pair = Pair.objects.create(
symbol=symbol, ask=ask, bid=bid, exchange_id=exchange_id
)
return redirect('/pair/')
You probably should not work with a permanent redirect, since then the browser will next time never trigger the logic, but visit the redirect directly.
Note: A GET request is not supposed to have side-effects, hence constructing objects when a user makes a GET request, is not compliant with the HTTP standard. Therefore it might be better to turn this into a POST request.