class Room (models.Model):
restaurant = models.ForeignKey(Restaurant,verbose_name='Restaurant', on_delete=models.CASCADE)
room_name = models.CharField(max_length=50,verbose_name='Room Name')
def __str__(self):
return self.room_name
class Table (models.Model):
room = models.ForeignKey(Room,on_delete=models.CASCADE)
capacity = models.IntegerField()
name = models.CharField(max_length=30,verbose_name='Table Name')
def __str__(self):
return self.room.room_name + ': ' + self.name
I'm using django to build an API and I want to return these models as a JSON. The problem is that when I return a Room object the Tables are not in the JSON. How can I serialise a Room and also get the tables serialised with it.
This is how I'm serialising the Room:
rooms = Room.objects.filter(restaurant=id)
return HttpResponse(serializers.serialize("json", rooms))
The problem is that the reverse relationship is not being included.
Related
I've defined some models in django and I can successfully add data to them using objects in django but the problem is that when I try to do this directly from the database it gives me this "HINT" There's a column named origin_id in the table flight, but it cannot be referenced from this part of the query, I'm using postgresql for the database, So can anyone please help me with this? I know there are similar questions like this but I couldn't find the solution.
class AirportManager(models.Manager):
#classmethod
def ret(cls):
return 'This is a custom "Manager"'
#classmethod
def code(cls):
obj = Airport.objects.all()
return obj
class Airport(models.Model):
code = models.CharField(max_length = 3)
city = models.CharField(max_length = 20)
objects = AirportManager()
class Meta:
db_table = 'airport'
def __str__(self):
return f"{self.city} ({self.code})"
class Flight(models.Model):
origin = models.ForeignKey(Airport,on_delete=models.CASCADE)
destination = models.ForeignKey(Airport,on_delete=models.CASCADE,related_name = "arrivals")
duration = models.IntegerField()
flights = models.Manager()
class Meta:
db_table = 'flight'
def __str__(self):
return f'from "{self.origin}" to "{self.destination}" in "{self.duration}" hrs'
my two model class:
class Bank(models.Model):
name = models.CharField(max_length=200)
def __str__(self):
return self.name
class Branch(models.Model):
ifsc = models.CharField(max_length=200)
name = models.CharField(max_length=200)
address = models.TextField(max_length=200)
city = models.CharField(max_length=200)
state = models.CharField(max_length=200)
bank = models.ForeignKey(Bank, on_delete=models.CASCADE,max_length=200)
def __str__(self):
return f"{self.name}"
serializer classes,
class BankSerializer(serializers.ModelSerializer):
class Meta:
model = Bank
fields = '__all__'
class BranchSerializer(serializers.ModelSerializer):
bank = serializers.CharField(source='bank.name', read_only=True)
class Meta:
model = Branch
fields = ["ifsc","name","address","city","state","bank"]
and Views.py
class CityBankNameView(APIView):
def get_object(self, bank_name, city_name):
try:
bank = Bank.objects.get(name=bank_name)
branches = Branch.objects.filter(bank__icontains=bank, city=city_name) #<-- icontains
return branches
except:
return HttpResponse(status=status.HTTP_404_NOT_FOUND)
def get(self,request, bank_name, city_name):
branches = self.get_object(bank_name, city_name)
serializer = BranchSerializer(branches, many=True)
return Response(serializer.data)
I am getting attribute error when using bank__icontains
exact error:
AttributeError at /branches/DELHI/AXIS BANK
Got AttributeError when attempting to get a value for field ifsc on serializer BranchSerializer.
The serializer field might be named incorrectly and not match any attribute or key on the bytes instance.
Original exception text was: 'bytes' object has no attribute 'ifsc'.
I am trying for hours but cannot find any solution to it. I seen various answers but none of them helps solve this one
bank__icontains= expects bank to be a string object, not a Bank object. You can thus rewrite the query to:
branches = Branch.objects.filter(bank=bank, city=city_name)
or if you want the Branches for which the name of the bank contains bank_name, you can filter with:
branches = Branch.objects.filter(bank__name__icontains=bank_name, city=city_name)
Here are the imports:
from django.db import models
from datetime import datetime, timedelta
This is the first class I did define. It is the status of the action (Actie) and it has a status-id and a status-name with a max_length attribute of 5 (todo, doing, done)
class Status(models.Model):
id = models.IntegerField(primary_key=True)
status_naam = models.CharField(max_length=5, default='todo')
def __str__(self):
return str(self.id) + " - " + self.status_naam
This class Gebruiker (what means user) just has an id and a username
class Gebruiker(models.Model):
id = models.IntegerField(primary_key=True)
gebruiker_naam = models.CharField(max_length=5, default='Naamloze gebruiker')
def __str__(self):
return str(self.id) + " - " + self.gebruiker_naam
This is the class Actie (Action or the action the user determines) which has an id, an action-name, a action-status which refers to the table Status here above, an action-publish-date, an ending-date (the deadline) and a user-id which refers to the table Gebruikers.
class Actie(models.Model):
id = models.IntegerField(primary_key=True)
actie_naam = models.CharField(max_length=150, default='-')
actie_status_id = models.ForeignKey(Status, default=1)
actie_aanmaakdatum = models.DateTimeField(default=datetime.now())
actie_einddatum = models.DateTimeField(default=datetime.now() + timedelta(days=1))
actie_gebruiker_id = models.ForeignKey(Gebruiker, default=1)
def __str__(self):
return str(self.id) + " - " + self.actie_naam
When I code the following in the Python-shell after importing the class: a = Actie(actie_naam='Bake a cake', actie_gebruiker_id=2)
I get the following error: ValueError: Cannot assign "2": "Actie.actie_gebruiker_id" must be a "Gebruiker" instance.
I have the same problem with Actie.actie_status_id but what important is for now is the user...
Please don't give ForeignKey fields names ending with _id. The field itself gives access to the entire related object, it is not an ID. Django will suffix the underlying database field with _id anyway.
So your model should be:
class Actie(models.Model):
...
actie_status = models.ForeignKey(Status)
...
actie_gebruiker = models.ForeignKey(Gebruiker)
Now your existing code will work. You could of course make your code work by doing a = Actie(actie_naam='Bake a cake', actie_gebruiker_id_id=2) but that would be silly.
(For the sake of completeness, you could also do gebruiker = Gebruiker.objects.get(id=2); a = Actie(actie_naam='Bake a cake', actie_gebruiker=gebruiker).)
(Also, there really isn't a good reason to give all your field names prefixes with the model name. That just adds verbosity for no benefit.)
I'm working on a site in Django where I have two models (players and seasons). I would like to display the players on a season page, but only when they are part of that season. Currently, this is what I have in my models file:
models.py
from django.db import models
class Player(models.Model):
pid = models.IntegerField(primary_key=True)
firstname = models.CharField(max_length=50)
lastname = models.CharField(max_length=50)
birthdate = models.DateField()
occupation = models.CharField(max_length=50)
city = models.CharField(max_length=50)
state = models.CharField(max_length=2)
def __str__(self):
name = self.firstname + " " + self.lastname
return name
class Season(models.Model):
sid = models.IntegerField(primary_key=True)
seasonname = models.CharField(max_length=50)
location = models.CharField(max_length=50)
#fsd is film start date
fsd = models.DateField()
#fed is film end date
fed = models.DateField()
#asd is air start date
asd = models.DateField()
#aed is air end date
aed = models.DateField()
def __str__(self):
return self.seasonname
class PxS(models.Model):
# Do I need a primary key on this? PROBABLY -- One to many relationship: one player, potential multiple seaons
pid = models.ForeignKey('Player', on_delete = models.CASCADE,)
sid = models.ForeignKey('Season', on_delete = models.CASCADE,)
# position they finished in
finishposition = models.IntegerField()
# total number of players that season
totalpositions = models.IntegerField()
def __str__(self):
name = "Player: " + str(self.pid) + " | Season: " + str(self.sid)
return name
Here is my views file for reference:
views.py
from django.shortcuts import render, get_object_or_404, redirect
from django.views.generic import ListView
from .models import Player, Season, PxS
def home(request):
seasons = Season.objects.order_by('sid')
return render(request, 'webapp/home.html', {'seasons': seasons})
def player(request, pk):
player = get_object_or_404(Player, pk=pk)
return render(request, 'webapp/player.html', {'player': player})
def season(request, pk):
season = get_object_or_404(Season, pk=pk)
return render(
request,
'webapp/season.html',
{'season': season, 'players': Player.objects.all()}
)
def seasons(request):
seasons = Season.objects.order_by('sid')
return render(request, 'webapp/seasons.html', {'seasons': seasons})
Currently, all players display on all season pages. I just can't figure out how to limit them. I've created a PxS model to link players with seasons based on foreign keys (pid and sid) but not sure how to implement them into the view. Am I missing something super obvious? Also, I believe it's a one to many relationship, because one player can be on multiple seasons. Is my thinking on this correct? Any insight is greatly appreciated.
PxS is the through table in a many-to-many relationship. You should define that relationship explicitly:
class Season(models.Model):
...
players = models.ManyToManyField('Player', through='PxS')
Now, in your season view, rather than sending all players explicitly to the template, you can just send the season; then when you iterate through seasons you can just use s.players.all to get the players for that season.
(Note, you shouldn't set primary keys explicitly unless you have a very good reason. Django automatically allocates an id field as the pk, so your PxS model does have one; the only thing you've done by defining the sid and pid pks explicitly is a) renaming them and b) disabling the autoincrement, which you certainly shouldn't do.)
I'd like to insert individual squawks into the Room object so I can insert into the database. How do I do this?
I tried, Room(squawk=squawk object), but this doesn't appear to work.
class Squawk(models.Model):
username = models.ForeignKey(User)
message = models.CharField(max_length=160)
time = models.DateTimeField(auto_now_add=True)
def __unicode__(self):
return str(self.username) + ' - ' + self.message
class Room(models.Model):
title = models.CharField(max_length=160)
created = models.DateTimeField(auto_now_add=True)
users = models.ManyToManyField(User)
squawks = models.ManyToManyField(Squawk)
def __unicode__(self):
return self.title
from django.shortcuts import get_object_or_404
# get Room instance by id or raise 404 page if not found
room = get_object_or_404(Room,pk = id)
# add squawk to many-to-many relation
room.squawks.add(squawk_object)
https://docs.djangoproject.com/en/dev/ref/models/relations/