Marshmallow Nested Serializer KeyError: u'Manager' - python

I'm using Marshmallow's nested serializers and getting the error "KeyError: u'manager'".
Here are my serializers:
class ShiftSerializer(Schema):
agent = fields.String()
date = fields.String()
end = fields.String()
status = fields.String()
class KPIShiftSerializer(Schema):
interval = fields.DateTime()
incoming = fields.Integer()
duration = fields.Decimal()
shifts_future = fields.Nested(ShiftSerializer, many=True)
shifts_current = fields.Nested(ShiftSerializer, many=True)
shifts_ending = fields.Nested(ShiftSerializer, many=True)
And my models:
class Shift(models.Model):
agent = models.CharField(default=" ", max_length=200)
date = models.CharField(default='01/01/1900', max_length=10)
end = models.DateTimeField(default=utc.localize(datetime(1900,1,1)))
status = models.CharField(default='Available', max_length=200)
class KPI(models.Model):
interval = models.DateTimeField(default=timezone.now)
incoming = models.IntegerField(default=0)
duration = models.FloatField(default=0)
shifts_future = models.ManyToManyField(Shift, related_name="returning")
shifts_current = models.ManyToManyField(Shift, related_name="staffed")
shifts_ending = models.ManyToManyField(Shift, related_name="leaving")

Related

Converting List to QuerySet Django

models.py
class Part(models.Model):
series = models.CharField(max_length=100)
number = models.CharField(max_length=100)
brand = models.CharField(max_length=100)
class Request(models.Model):
part_number = models.ForeignKey(Part, on_delete=models.CASCADE)
brand = models.CharField(max_length=100)
quantity = models.PositiveIntegerField()
date = models.DateField()
class Quota(models.Model):
part_number = models.ForeignKey(Part, on_delete=models.CASCADE)
brand = models.CharField(max_length=100)
quantity = models.PositiveIntegerField()
price = models.DecimalField(max_digits=10, decimal_places=2)
supplier = models.CharField(max_length=100)
date = models.DateField()
views.py
def requests_and_quotas(request):
requests = Request.objects.all()
quotas = Quota.objects.all()
result = []
for req in requests:
match = False
for quo in quotas:
if (req.part_number.series == quo.part_number.series) and (abs((req.date - quo.date).days) <= 2):
result.append({'request': req, 'quota': quo})
if not match:
result.append({'request': req, 'quota': None})
return render(request, 'requests_and_quotas.html', {'result': result,})
I wanted to connect django_filters, but ran into a problem AttributeError: 'list' object has no attribute '_meta'. How can I change the logic of my code to retrieve a QuerySet object?
result_qs = QuerySet(result) it didn't help
You can create a list of ids of your objects in the list. Then simply filter by them.
instances = [<MyModel: 1>, <MyModel: 2>]
list_of_ids = [inst.id for inst in instances]
queryset = MyModel.objects.filter(id__in=list_of_ids)

rest_marshmallow: Nested Schema isn't loading

I have trouble getting the nested Schema loaded using marshmallow serializer.
models.py
from django.db import models
class User(models.Model):
first_name = models.CharField(max_length=200)
last_name = models.CharField(max_length=200)
email = models.CharField(max_length=200, unique=True)
created = models.DateTimeField(auto_now_add=True)
last_updated = models.DateTimeField(auto_now=True)
class Upload(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
state = models.CharField(max_length=200)
created = models.DateTimeField(auto_now_add=True)
class Location(models.Model):
upload = models.ForeignKey(Upload, on_delete=models.CASCADE)
lat = models.FloatField()
long = models.FloatField()
serializers.py
from rest_marshmallow import Schema, fields
class LocationSchema(Schema):
lat = fields.String()
long = fields.String()
class UploadsSchema(Schema):
id = fields.Integer()
state = fields.String()
location = fields.Nested(LocationSchema)
user_id = fields.Integer()
created = fields.DateTime()
class UserSchema(Schema):
id = fields.Integer()
first_name = fields.String()
last_name = fields.String()
email = fields.Email()
created = fields.DateTime()
last_updated = fields.DateTime()
views.py
class UploadsView(ListView):
def get(self, request, user_id):
upload = Upload.objects.filter(user_id=user_id)
serializer = UploadsSchema(upload, many=True)
return JsonResponse(serializer.data, safe=False)
def post(self, request, user_id):
data = json.loads(request.body)
user = User.objects.get(id=user_id)
upload = Upload(state=data['state'], user=user)
upload.save()
recent_upload = Upload.objects.filter(user_id=user_id).latest('created')
location = Location(lat=data['lat'], long=data['long'], upload=recent_upload)
location.save()
message = {
"data": "Success"
}
return JsonResponse(message, safe=False)
GET on UploadsView returns all the fields except the Nested field.
Here's a sample response:
{
"user_id": 2,
"id": 5,
"created": "2022-08-05T17:44:30.829087+00:00",
"state": "happy"
}
I tried location = fields.Nested(LocationSchema(many=True)), but that doesn't seem to work either. What am I doing wrong here? TIA.

Add object to to manytomany relationship

i'm trying to add ticker values to a currency object using a custom command, but i can't seem to be able to add the ticker to the CurrencyTickerSerializer? i get following error TypeError: 'QuerySet' object does not support item assignment. I run this command in a specific interval that is suppose to add the ticker into the specific currency, but i guess i need to add something in order to being able to add the ticker into TickerSerializer?
Command
class Command(BaseCommand):
def handle(self, *args, **options):
comparison='DKK'
url = 'URL'
page = requests.get(url)
data = page.json()
response_data = {}
for ticker in data:
currency = Currency.objects.filter(symbol=ticker['symbol'], is_active=True)
if currency.exists():
currency['tickers'] = ticker
serializer = CurrencyTickerSerializer(data=currency)
if serializer.is_valid():
serializer.save()
serializers
class TickerSerializer(serializers.HyperlinkedModelSerializer):
currency = serializers.PrimaryKeyRelatedField(many=False, queryset=Currency.objects.all())
class Meta:
model = Ticker
fields = ('currency', 'rank', 'price_dkk', 'market_cap_dkk', 'percent_change_1h', 'percent_change_24h', 'percent_change_7d',)
class CurrencyTickerSerializer(serializers.HyperlinkedModelSerializer):
tickers = TickerSerializer(many=True)
class Meta:
model = Currency
fields = ('id', 'name','symbol', 'tickers', )
Models
class Ticker(models.Model):
rank = models.IntegerField()
price_dkk = models.DecimalField(max_digits=20, decimal_places=6)
market_cap_dkk = models.BigIntegerField()
percent_change_1h = models.DecimalField(max_digits=4, decimal_places=2)
percent_change_24h = models.DecimalField(max_digits=4, decimal_places=2)
percent_change_7d = models.DecimalField(max_digits=4, decimal_places=2)
created_at = models.DateTimeField(auto_now_add=True)
class Meta:
verbose_name_plural = _('Ticker')
def __str__(self):
return self.id
class Currency(models.Model):
symbol = models.CharField(max_length=4, default='BTC', unique=True)
name = models.CharField(max_length=20, default='Bitcoin', unique=True)
img = models.ImageField(upload_to = 'static/img/currencies', blank=True)
is_active = models.BooleanField(default=False)
tickers = models.ManyToManyField(Ticker)
class Meta:
verbose_name_plural = 'currencies'
def __str__(self):
return self.name
let review your code where is this problem .
class Command(BaseCommand):
def handle(self, *args, **options):
comparison='DKK'
url = 'URL'
page = requests.get(url)
data = page.json()
response_data = {}
for ticker in data:
currency = Currency.objects.filter(symbol=ticker['symbol'], is_active=True)
if currency.exists():
currency['tickers'] = ticker
serializer = CurrencyTickerSerializer(data=currency)
if serializer.is_valid():
serializer.save()
your code is working until currency['tickers'] = ticker you treat a class as array.use currency.tickers.add(ticker) instate . it will work but not in your case because add function will complain about argument . it's need a instance Ticker class not json data . so know
for ticker in data:
currency = Currency.objects.filter(symbol=ticker['symbol'], is_active=True)
if currency.exists():
tickers = Ticker(...)
currency.tickers.add(tickers)
serializer = CurrencyTickerSerializer(data=currency)

Django AttributeError:'Campaign' object has no attribute 'ads'

I am trying to create in a nested serializer in Django Rest Framework but I keep getting this error. I know why it's throwing it but, i thought Django would handle the one-to-many relationship.
AttributeError at /api/campaigns
Got AttributeError when attempting to get a value for field ads on serializer CampaignSerializer.
The serializer field might be named incorrectly and not match any attribute or key on the Campaign instance.
Original exception text was: 'Campaign' object has no attribute 'ads'.
class Campaign(models.Model):
name = models.CharField(max_length = 30)
type = models.CharField(max_length = 20)
start_date = models.DateField(auto_now=False, auto_now_add=True)
end_date = models.DateField(auto_now=False, auto_now_add=True)
locations = models.CharField(max_length = 30)
budget = models.IntegerField()
land_page = models.URLField()
keywords = models.TextField()
CPM = models.IntegerField()
CPC = models.IntegerField()
description = models.TextField()
commission = models.IntegerField()
pay_off = models.IntegerField()
advertiser = models.ForeignKey(User)
date_time = models.DateField(auto_now=False, auto_now_add=True)
class Meta:
db_table = "campaigns"
class ADS(models.Model):
advertiser = models.ForeignKey(User)
campaign = models.ForeignKey(Campaign)
headline = models.CharField(max_length=50)
description_1 = models.TextField(blank=True)
description_2 = models.TextField(blank=True)
display_url = models.URLField(blank=True)
final_url = models.URLField(blank=True)
mobile_url = models.URLField(blank=True)
class Meta:
db_table = "ads"
These are my serializers
class ADSerializer(serializers.ModelSerializer):
adsImages = AdsImagesSerializer(read_only=True,many=True)
class Meta:
model = ADS
fields = ("headline","description_1","description_2","display_url","final_url","mobile_url","advertiser","adsImages")
class CampaignSerializer(serializers.ModelSerializer):
advertiser = AdvertiserProfile(read_only=True,required=False)
ads = ADSerializer(many=True)
class Meta:
model = Campaign
fields = ("name","type","start_date","end_date","locations","budget","land_page","keywords","CPM","CPC","description","commission","pay_off","ads","advertiser",)
def get_validation_exclusions(self, *args, **kwargs):
exclusions = super(CampaignSerializer,self).get_validation_exclusions()
return exclusions + ['advertiser']
def create(self, validated_data):
ads_data = validated_data.pop('ads')
campaign = Campaign.objects.create(**validated_data)
for ad_data in ads_data:
ADS.objects.create(campaign=campaign, **ad_data)
return campaign
I just fixed this, with a related name in the model
campaign = models.ForeignKey(Campaign, related_name="ads")
I think it didn't worked last time because the reverse relationship was not working without a related_name.

Getting other tables Django filter/select_related

I am trying to filter values using Django's filter and select_related. I am able to get the base item, but I can't get any of the joined fields.
item = Items.objects.filter(tests__company_user_id__user_id=user_id).filter(item_id=item_id).select_related("tests__company_user").values()
My goal is to get data from the user associated with the item onto the item return. Is this possible?
The data model looks like this:
class Items(models.Model):
item_id = models.CharField(primary_key=True,max_length=100)
mailed_date = models.DateTimeField()
received_date = models.DateTimeField()
last_viewed = models.DateTimeField()
dateitemsent = models.DateTimeField()
itemsent = models.CharField(max_length=25)
itemret = models.CharField(max_length=25)
dateitemret = models.DateTimeField()
status = models.CharField(max_length=25)
class Tests(models.Model):
tests_id = models.CharField(primary_key=True, unique=True, max_length=100)
teststypetest_id = models.ForeignKey(TestsType)
dateitemord = models.DateTimeField()
testdate = models.DateTimeField()
teststypetest_id = models.ForeignKey(TestsType)
dateitemord = models.DateTimeField()
testdate = models.DateTimeField()
status = models.CharField(max_length=100)
item_id = models.ForeignKey(Kits)
company_user_id = models.ForeignKey(CompanyUser)
class CompanyUser(models.Model):
user_id = models.CharField(primary_key=True,max_length=100)
username = models.CharField(max_length=254,default="empty")
sec_question_1 = models.CharField(max_length=254)
sec_answer_1 = models.CharField(max_length=254)
sec_question_2 = models.CharField(max_length=254)
sec_answer_2 = models.CharField(max_length=254)
sec_question_3 = models.CharField(max_length=254)
sec_answer_3 = models.CharField(max_length=254)
When you use select_related() you are caching joined object info but not retrieving, you need explicitly pull data:
item = Items.objects.filter(tests__company_user_id__user_id=user_id).filter(item_id=item_id).select_related("tests__company_user").values("tests__company_user_id__sec_question_1", "tests__company_user_id__sec_question_2", ...)
EDIT
Let's suppose you just want 2 fields from CompanyUser: sec_question_1 and sec_question_2:
from django.db.models import F
item = Items.objects.filter(tests__company_user_id__user_id=user_id).filter(item_id=item_id).select_related("tests__company_user").values().annotate(q1=F('tests__company_user_id__sec_question_1'), q2=F('tests__company_user_id__sec_question_2'))

Categories