How to order by nested objects fields? - angularjs

I have some classes
class MarketProduct(models.Model, ObjectMarket):
_state_class = 'MarketProductState'
uuid = models.UUIDField(u'Код',
default=uuid.uuid4, editable=False)
name = models.CharField(u'Название',
max_length=255, db_index=True)
class MarketItem(models.Model, ObjectMarket):
_state_class = 'MarketItemState'
STOCK, AUCTION = 1, 2
ITEM_CHOICES = (
(STOCK, u'Сток'),
(AUCTION, u'Аукцион'),
)
product = models.ForeignKey(MarketProduct)
start_at = models.DateTimeField(u'Начало продажи')
I want to get MarketItemViewSet and use
filter_backends = (filters.OrderingFilter,`)
I send request with filed orderby by angular.
If I send orderby = start_at, all are good, but I want to send
orderby = product.id, it doesn't work.

You can try specifying product__id to perform ordering based on the id of product.
orderby = product__id
Specify ordering_fields in your viewset.
ordering_fields = ('product__id', )

As you are using django-rest-framework you have to use ordering_fields as you can see from the documentation here.Hope it helps example:
class UserListView(generics.ListAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
filter_backends = (filters.OrderingFilter,)
ordering_fields = ('username', 'email')
ordering = ('created_on') # for reverse ordering = ('-created_on')
If an ordering attribute is set on the view, this will be used as the default ordering.
Typically you'd instead control this by setting order_by on the initial queryset, but using the ordering parameter on the view allows you to specify the ordering in a way that it can then be passed automatically as context to a rendered template

Related

getting a django model field from another field

i have this model
class Person(models.Model):
picture = models.ImageField(
default='default.jpg', upload_to='profile_pics', )
firstName = models.CharField(blank=True, max_length=100)
familyName = models.CharField(blank=True, max_length=100)
age = models.IntegerField(default=0)
GENDER = [
("M", 'Male'),
("F", 'Female'),
("U", 'UNKNOWN'),
]
gender = models.CharField(
max_length=2,
choices=GENDER,
default="U",
)
address = models.CharField(blank=True, max_length=100)
remark = models.TextField(default="no remark")
description_vector = models.TextField(blank=True)
i want to infer the description_vector from the picture field (with a method called identifie(pictur) that return a string ) whenever i add a new Person or changing a model image (if the image didn't change i dont want to change the description_vector)
i know i can use the save method like here but i dont know how to specify that when the image change the vector change.
i dont know if it changes anything but i use django-rest-framowrk to add and change persons
i know
I am not sure I understand what your specific doubt is, but I think this might be helpful.
def save(self, *args, **kwargs):
if self.id is not None: # check only when update
original_picture = self.objects.get(id=self.id).picture
if original_picture !== self.picture # You must add here your method to evaluate if both images are equal
self.vector = some_method_to_change_vector(self.picture)
return super().save(*args, **kwargs)

DRF - queryset filter using contains field lookup on SlugRelatedField

I am struggling to figure out the how to run queryset filter using "field__contains" on a SlugRelatedField.
I have a simple Book model and a Tag model that looks as following:
class Book(models.Model):
title = models.CharField(max_length=100)
authors = models.ManyToManyField(Author)
publisher = models.ForeignKey(Publisher)
publication_date = models.DateField()
class MetaTag(models.Model):
book = models.ManyToManyField('Book', related_name='meta_tags',
help_text='The book this meta tag belongs to')
value = models.CharField(max_length=400, unique=True, help_text='Meta tag value')
class BookSerializer(serializers.HyperlinkedModelSerializer):
class BookHyperlink(serializers.HyperlinkedIdentityField):
"""A Hyperlink field for book details"""
def get_url(self, obj, view_name, request, format):
url_kwargs = {
'pk': obj.id,
}
return reverse(view_name, kwargs=url_kwargs, request=request, format=format)
url = BookHyperlink(view_name='book-detail')
meta_tags = CreatableSlugRelatedField(many=True, slug_field='value', queryset=MetaTag.objects.all())
class Meta:
model = Book
fields = (
'id',
'title',
'publisher',
'publication_date',
'meta_tags',
'url'
)
class MetaTagSerializer(serializers.ModelSerializer):
class Meta:
model = MetaTag
fields = ('id', 'book', 'value',)
class CreatableSlugRelatedField(serializers.SlugRelatedField):
def to_internal_value(self, data):
try:
return self.get_queryset().get_or_create(**{self.slug_field: data})[0]
except ObjectDoesNotExist:
self.fail('does_not_exist', slug_name=self.slug_field, value=smart_text(data))
except (TypeError, ValueError):
self.fail('invalid')
class Meta:
model = MetaTag
fields = ('id', 'book', 'value', )
Now in my BooksView, I want to be able to filter the queryset by meta_tags value. I've tried the following with "__contains" field lookup:
class Books(viewsets.ModelViewSet):
"""Default view for Book."""
queryset = Book.objects.all()
serializer_class = BookSerializer
permission_classes = (IsAuthenticated, )
filter_backends = (DjangoFilterBackend,)
filter_fields = tuple(f.name for f in Book._meta.get_fields())
def get_queryset(self):
search_pattern = self.request.query_params.get('search', None)
if search_pattern is not None and search_pattern is not '':
self.queryset = self.queryset.filter(meta_tags__contains = search_pattern)
return self.queryset
def get_object(self):
if self.kwargs.get('pk'):
return Book.objects.get(pk=self.kwargs.get('pk'))
But I get the following error from django:
File "~MyProject/venv/lib/python3.6/site-packages/django/db/models/sql/query.py", line 1076, in build_lookup
raise FieldError('Related Field got invalid lookup: {}'.format(lookup_name))
django.core.exceptions.FieldError: Related Field got invalid lookup: contains
Which as I understand means that since "meta_tags" is not a regular array or Text field, the contains field lookup cannot be applied on that field.
What is the best way if so to filter the queryset in such case for meta_tags value?
A django expert I've consulted about this issue, suggested to try append the "slug_field" ("__value" in this case) to "__contains" field lookup when used with external model.
It was not documented anywhere or even on django official documentation at https://docs.djangoproject.com/en/2.0/ref/contrib/postgres/fields/#contains, so I had no way to know it works this way, but this solution actually works:
queryset = queryset.filter(meta_tags__value__contains=search_pattern)
It actually makes sense when you look deeper at the MetaTag model, as "value" is the inner field of the meta_tags model:
class MetaTag(models.Model):
book = models.ManyToManyField('Book', related_name='meta_tags',
help_text='The book this meta tag belongs to')
value = models.CharField(max_length=400, unique=True, help_text='Meta tag value')
def __str__(self):
return '%s > %s' % (self.channel, self.value)
The reason it was not so obvious to append __value at the first place is because meta_tags array (array of objects) is flattened using the SlugRelatedField serializer where only the slug_field is projected and the rest fields are omitted.
So the final output of meta_tags array is flat:
meta_tags: ['tag1','tag2']
instead of:
meta_tags: [{book: 'a', value: 'tag1'},{book: 'a', value: 'tag2'}]
But since serialization on django DRF is made on a late stage (after queryset is completed) the original field schema should be considered.
Hope this will save somebody's headache someday.

Query for repeated ndb.KeyProperty not working

What's wrong with my query?
Here are my models:
class Positions(ndb.Model):
title = ndb.StringProperty(indexed=True)
summary = ndb.TextProperty()
duties = ndb.TextProperty()
dateCreated = ndb.DateTimeProperty(auto_now_add=True)
dateUpdated = ndb.DateTimeProperty(auto_now=True)
class Applicants(ndb.Model):
name = ndb.StringProperty(indexed=True)
position = ndb.KeyProperty(kind=Positions,repeated=True)
file = ndb.BlobKeyProperty()
dateCreated = ndb.DateTimeProperty(auto_now_add=True)
dateUpdated = ndb.DateTimeProperty(auto_now=True)
Here is my query:
class AdminPositionInfoHandler(BaseHandler):
def get(self,positionKeyId):
user = users.get_current_user()
if users.is_current_user_admin():
positionKey = ndb.Key('Positions',int(positionKeyId))
position = positionKey.get()
applicants = Applicants.query(position=position.key).fetch() # the query
values = {
'position': position,
'applicants': applicants,
}
self.render_html('admin-position-info.html',values)
else:
self.redirect(users.create_login_url(self.request.uri))
What seems to be wrong in using the query:
applicants = Applicants.query(position=position.key).fetch()
I got this error:
File "C:\xampp\htdocs\angelstouch\main.py", line 212, in get
applicants = Applicants.query(position=position.key).fetch()
...
TypeError: __init__() got an unexpected keyword argument 'position'
I also tried using positionKey instead of position.key:
applicants = Applicants.query(position=positionKey).fetch()
I got this from "Ancestor Queries" section of GAE site:
https://developers.google.com/appengine/docs/python/ndb/queries
You don't pass arguments to query like that - ndb uses overridden equality/inequality operators, so you can express queries more 'naturally', with '==', '<', '>' etc., so:
applicants = Applicants.query(Applications.position==position.key).fetch()
The section in the on Filtering by Property Values gives some more examples.
(ancestor is a special-case for queries - it isn't a model property)

django 1.5 Get latest records by Date

I want to get all the records that have the latest date.
class Report(models.Model):
id = models.AutoField(primary_key=True)
part = models.ForeignKey(Part,related_name="reports")
this_week_use = models.IntegerField(blank=True,null=True,default=0)
this_week_fail = models.IntegerField(blank=True,null=True,default=0)
this_week_fail_percent = models.DecimalField(max_digits=5,decimal_places=2,blank=True,null=True,default=0.00)
prev4_week_use = models.IntegerField(blank=True,null=True,default=0)
prev4_week_fail = models.IntegerField(blank=True,null=True,default=0)
prev4_week_fail_percent = models.DecimalField(max_digits=5,decimal_places=2,blank=True,null=True,default=0.00)
platform = models.ForeignKey(Platform,related_name="reports")
date = models.DateField(auto_now_add=True)
class Meta:
unique_together = ('part','platform','date')
I tried
rows = Report.objects.annotate(max_date=Max('date').filter(date=max_date))
Which resulted in no data
Use latest() method
Report.objects.latest('date')
You can use order_by, it's available in 1.5:
latest_rows = Report.objects.all().order_by('-date')
If you want any query in Your report model, by default ordered by this date field, then you can add this ordering on the meta section of your Report model.
class Report(models.Model):
class Meta:
ordering = '-date'
Now you can make query without using order_by in your query, but with same result:
latest_rows = Report.objects.all()
If you don't mind to make two queries, this should do it:
max_date = Report.objects.latest('date').date
qs = Report.objects.filter(date=max_date)

Django - filter by foreign key string

main table:
class example(models.Model):
name = models.CharField('Item Name', max_length=200)
color = models.ManyToManyField(Color)
category = models.ForeignKey(Category)
image = models.ImageField('Item Image',upload_to="example/images/")
Category table:
class Category(models.Model):
catname = models.CharField('Category Name',max_length=100)
How can i query it while filtering the example table according to the category.
This didn't work out:
def list(request, cat):
c = example.object.filter(category = cat)
What should i change to make this filtering work ?
See Django's documentation on related lookups:
def list(request, cat):
c = example.objects.filter(category__catname=cat)

Resources