Backbone-Relational and Django-Tastypie: many-to-many fields operating example - many-to-many

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

To return custom field in DjangoRestFramework after aggregation

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

Why is my Django serializer telling me an attribute doesn't exist when I see it defined in my model?

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']

FilterSet for ManyToMany relationship existence

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

How to implement ForeignKey with Django serializer

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.

Django rest-framework + polymorphic: serialize a list of URLs

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')