May somebody provide an example of operating with many-to-many fields of django.db models' instances through django-tastypie and backbone-relational? That's possible now with using intermediate model.
from django.db import models
class Author(models.Model):
name = models.CharField(max_length=42)
class Book(models.Model):
authors = models.ManyToManyField(Author, related_name='books', through='Authorship')
title = models.CharField(max_length=42)
class Authorship(models.Model):
author = models.ForeignKey(Author)
book = models.ForeignKey(Book)
Here are possible tastypie resources' configuration:
from tastypie import fields, resources
class AuthorResource(resources.NamespacedModelResource):
books = fields.ToManyField('library.api.resources.AuthorshipResource', 'books')
class Meta:
resource_name = 'author'
queryset = models.Author.objects.all()
class BookResource(resources.NamespacedModelResource):
authors = fields.ToManyField('library.api.resources.AuthorshipResource', 'authors')
class Meta:
resource_name = 'book'
queryset = models.Book.objects.all()
class AuthorshipResource(resources.NamespacedModelResource):
author = fields.ToOneField('library.api.resources.AuthorResource', 'author')
book = fields.ToOneField('.api.resources.BookResource', 'book')
class Meta:
resource_name = 'authorship'
queryset = models.Authorship.objects.all()
How to save Author related with a few unsaved yet Books using one request to our server?
Related
There are lot of answers related to custom fields on stackoverflow but when trying with them, I am getting different error, so posting a separate question.
I wanted to return a JSON Response for the following url
urls.py
path('cards/<int:pk>/smarts', smarts.as_view(), name="smarts"),
I will be using below api.py file to return aggregate fields using Transaction model, the query is working fine, I only have to return appropriate response. Here I have one of the fields as Decimal hence tried with DjangoJSONEncoder but got an error.
api.py
class smarts(generics.ListAPIView):
serializer_class = TransactionSerializer
permission_classes = [permissions.IsAuthenticated, TransactionIsOwnerOrNot]
def get_queryset(self):
card = get_object_or_404(self.request.user.cards, pk=self.kwargs['pk'])
qs=card.transactions.values('vendor').annotate(a=Count('pk'),b=Sum('amount')).order_by('-b')
....CODE REQUIRED
return ....
models.py
class Transactions(models.Model):
amount = models.DecimalField(max_digits=19, decimal_places=2)
vendor = models.CharField(max_length=200)
category = models.CharField(max_length=200)
owner = models.ForeignKey(Cards, on_delete=models.CASCADE, related_name="transactions",null=True)
serializer.py
class TransactionSerializer(serializers.ModelSerializer):
class Meta:
model = Transactions
fields = '__all__'
I found the answer after hit and trial, I used custom serializer to return required field.
serializer.py
class SmartSerializer(serializers.Serializer):
vendor = serializers.CharField(max_length=200)
tot = serializers.IntegerField()
tot_amt = serializers.DecimalField(max_digits=19, decimal_places=2)
api.py
class smartstatements(generics.ListAPIView):
permission_classes = [permissions.IsAuthenticated, TransactionIsOwnerOrNot]
serializer_class = SmartSerializer
def get_queryset(self):
card = get_object_or_404(self.request.user.cards, pk=self.kwargs['pk'])
queryset=card.transactions.values('vendor')
.annotate(tot=Count('pk'),tot_amt=Sum('amount'))
.order_by('-tot_amt')
return queryset
I'm using Python 3.7 and the Django rest framework to serialize some models into JSOn data. I have this
data = {
'articlestats': ArticleStatSerializer(articlestats, many=True).data,
and then I have defined the following serializers ...
class LabelSerializer(serializers.ModelSerializer):
class Meta:
model = Label
fields = ['name']
...
class ArticleSerializer(serializers.ModelSerializer):
label = LabelSerializer()
class Meta:
model = Article
fields = ['id', 'title', 'path', 'url', 'label']
class ArticleStatSerializer(serializers.ModelSerializer):
article = ArticleSerializer()
class Meta:
model = ArticleStat
fields = ['id', 'article', 'score']
I have defined my Label model like so ...
class Label(models.Model):
name = models.CharField(max_length=200)
def __str__(self):
return self.name
class Meta:
unique_together = ("name",)
but I'm getting this error when Django processes my serialize line ...
AttributeError: Got AttributeError when attempting to get a value for field `name` on serializer `LabelSerializer`.
The serializer field might be named incorrectly and not match any attribute or key on the `str` instance.
Original exception text was: 'str' object has no attribute 'name'.
Not sure why it's complaining. The "name" attribute is right there. What else should I be doing?
Edit: Models asked for ...
class ArticleStat(models.Model):
objects = ArticleStatManager()
article = models.ForeignKey(Article, on_delete=models.CASCADE, related_name='articlestats')
score = models.FloatField(default=0, null=False)
class Article(models.Model):
objects = ArticleManager()
title = models.TextField(default='', null=False)
path = models.TextField(default='', null=False)
url = models.TextField(default='', null=False)
label = models.TextField(default='', null=True)
created_on = models.DateTimeField(db_index=True, default=datetime.now)
In Article model the label field is TextField, not any kind of related fields. But in your serializer, it expects a related field.
class ArticleSerializer(serializers.ModelSerializer):
label = LabelSerializer()
class Meta:
model = Article
fields = ['id', 'title', 'path', 'url', 'label']
Basic models:
class ModelA(Model):
name = CharField(...)
class ModelB(Model):
model_a = ManyToManyField(ModelA, blank=True)
class ModelBFilter(filters.FilterSet):
unassigned = BooleanFilter(field_name='model_a', lookup_expr='isnull')
class Meta:
model = ModelB
fields = ['unassigned']
How do I filter (with django-filter) to find the ModelB's that do not have a corresponding related model?
It looks to me that what you have should work. Perhaps the fields = ['unassigned'] is unnecessary? According to the documentation you can also negate the filter thusly:
class ModelBFilter(filters.FilterSet):
assigned = BooleanFilter(field_name='model_a', lookup_expr='isnull', exclude=True)
class Meta:
model = ModelB
I have this models:
class Discipline(models.Model):
name = models.CharField(max_length=200)
class Lesson(models.Model):
discipline = models.ForeignKey(Discipline, on_delete=models.CASCADE, null=True)
date = models.DateField()
regular_slot = models.BooleanField(default=False)
And these serializers:
class DisciplineSerializer(serializers.ModelSerializer):
class Meta:
model = Discipline
fields = ('name')
class LessonSerializer(serializers.ModelSerializer):
discipline = serializers.RelatedField(source='Discipline', read_only=True);
class Meta:
model = Lesson
fields = ('discipline', 'date', 'regular_slot')
I have a view to process a JSON request and to save the data:
def cours_list(request):
if request.method == 'POST':
data = JSONParser().parse(request)
serializer = LessonSerializer(data=data)
if serializer.is_valid():
serializer.save()
return JSONResponse(serializer.data, status=201)
return JSONResponse(serializer.errors, status=400)
My JSON request is as follows:
{"discipline":"Mathematiques","date":"2017-12-03"}
However, I have an error saying that:
'Lesson' object has no attribute 'Discipline'
I believe this is because attribute discipline in Lesson refers only to the id and is not of type Discipline. I could'nt find how to solve this. Is the way I define foreignKey is not correct ?
How to insert a foreignKey reference here while I receive a Discipline object from the JSON request ?
I'm going to help you also with this :)
class DisciplineSerializer(serializers.ModelSerializer):
class Meta:
model = Discipline
fields = ('name')
class LessonSerializer(serializers.ModelSerializer):
discipline = DiscliplineSerializer()
class Meta:
model = Lesson
fields = ('discipline', 'date', 'regular_slot')
Doing this is enough as far as I know.
Edit: Reason of your error is that you write "source="Discipline"" but there is no field named Discipline in your Lesson model. Therefore, it gives an error.
The relevant parts of my model:
class Item(PolymorphicModel):
rating = models.DecimalField(default=0.0, max_digits=5, decimal_places=2)
picture = models.URLField(max_length=200)
category = models.ForeignKey('Category', related_name='items')
# url_list
class Movie(Item):
title = models.CharField(max_length=200)
description = models.CharField(max_length=2000)
...
I would like to have a list of urls in the Item class. This list should be serialized in the movie object serializer.
So far I tried to create a model to represent a URL this way:
class Url(models.Model):
url = models.URLField(max_length=200)
item = models.ForeignKey('Item', related_name='pictures')
But I get an empty list when a movie is serialized. My Serializers are:
class UrlSerializer(serializers.ModelSerializer):
class Meta:
model = ScrollerPictureUrl
fields = ('url',)
class MovieSerializer(serializers.ModelSerializer):
urls = UrlSerializer(many=True)
class Meta:
model = Movie
exclude = ('polymorphic_ctype', 'category')
I need to know how to serialize the url list for the Movie object so that it's not empty.
That's what I did finally:
class MovieSerializer(serializers.ModelSerializer):
urls = serializers.SlugRelatedField(many=True, slug_field='url')
class Meta:
model = Movie
exclude = ('polymorphic_ctype', 'category')