I am trying to display the variants(field) that are related to the model RecordVariant on my webpage i have queryset on my view default how can i change my queryset or get queryset method to display variants that are related to particular record.
class RecordVariant(models.Model):
variants = models.ForeignKey(Variant_model, related_name = 'records', on_delete =
models.CASCADE)
class Variant(models.Model):
name = models.CharField(max_length = 23, blank=True, null=True)
class RecordVariantListAPIView(RecordMixin, ListAPIView):
lookup_url_kwarg = 'record_id'
serializer_class = RecordVariantSerializer
permission_classes = [IsAuthenticated]
pagination_class = StandardResultsSetPagination
filter_backends = (filters.OrderingFilter,)
queryset = RecordVariant.objects.all()
ordering = 'variants'
ordering_param = 'ordering'
ordering_fields = (
'variants',
)
def get_total_queryset(self):
queryset = (
super()
.get_queryset()
.filter(record=self.record)
)
in foreignkey relations the child should be the one with foreginkey field.
meaning your Variant model class should have this field
class Variant(models.Model):
name = models.CharField(max_length = 23, blank=True, null=True)
records = models.ForeignKey(RecordVariant, related_name = 'records',
on_delete = models.CASCADE)
class RecordVariant(models.Model):
pass
and for the serializers
class Variant(serializers.ModelSerializer):
class Meta:
model = Variant
fields = "['name']"
class RecordVariant(serializers.ModelSerializer):
records = VariantSerializer(many=True)
class Meta:
model = RecordVariant
fields = '__all__'
the view
class RecordVariantListAPIView(ListAPIView):
serializer_class = RecordVariantSerializer
permission_classes = [IsAuthenticated]
queryset = RecordVariant.objects.all()
Related
I am trying to update the OrderItem model using update_or_create() method. OrderItem model is related to the Order model with many to one relationship ie with a Foreignkey.
I am trying to query the orderitem object using id and update the related fields using default as you can see, but got this error.
My models:
class Order(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, blank=True)
ordered_date = models.DateTimeField(auto_now_add=True)
ordered = models.BooleanField(default=False)
total_price = models.CharField(max_length=50,blank=True,null=True)
#billing_details = models.OneToOneField('BillingDetails',on_delete=models.CASCADE,null=True,blank=True,related_name="order")
def __str__(self):
return self.user.email
class Meta:
verbose_name_plural = "Orders"
ordering = ('-id',)
class OrderItem(models.Model):
#user = models.ForeignKey(User,on_delete=models.CASCADE, blank=True)
order = models.ForeignKey(Order,on_delete=models.CASCADE, blank=True,null=True,related_name='order_items')
item = models.ForeignKey(Product, on_delete=models.CASCADE,blank=True, null=True)
order_variants = models.ForeignKey(Variants,on_delete=models.CASCADE,blank=True,null=True)
quantity = models.IntegerField(default=1)
ORDER_STATUS = (
('To_Ship', 'To Ship',),
('Shipped', 'Shipped',),
('Delivered', 'Delivered',),
('Cancelled', 'Cancelled',),
)
order_item_status = models.CharField(max_length=50,choices=ORDER_STATUS,default='To_Ship')
My view:
class UpdateOrderView(UpdateAPIView):
permission_classes = [AllowAny]
queryset = Order.objects.all()
serializer_class = OrderUpdateSerializer
My serializers:
class OrderUpdateSerializer(serializers.ModelSerializer):
order_items = OrderItemUpdateSerializer(many=True)
billing_details = BillingDetailsSerializer()
class Meta:
model = Order
fields = ['id','ordered','order_status','order_items','billing_details']
def update(self, instance, validated_data):
instance.order_status = validated_data.get('order_status')
instance.ordered = validated_data.get('ordered')
#billing_details_logic
billing_details_data = validated_data.pop('billing_details',None)
if billing_details_data is not None:
instance.billing_details.address = billing_details_data['address']
instance.billing_details.save()
#order_items_logic
instance.save()
order_items_data = validated_data.pop('order_items')
# print(order_items_data)
#instance.order_items.clear()
for order_items_data in order_items_data:
oi, created = OrderItem.objects.update_or_create(
id= order_items_data['id'],
defaults={
'quantity' : order_items_data['quantity'],
'order_item_status': order_items_data['order_item_status']
}
)
super().update(instance,validated_data)
return oi
Updated serializer:
for order_item_data in order_items_data:
oi, created = instance.order_items.update_or_create(
id= order_item_data['id'],
defaults={
'quantity' : order_item_data['quantity'],
'order_item_status': order_item_data['order_item_status']
}
)
The order_items data are sent like this.
order_items_data is a list.
Then you iterate over it with the same variable name.
for order_items_data in order_items_data:
Just rename it to something like
for order_data in order_items_data:
and there will be an id in your order_data.
I wasn't getting the id on the OrderedDict also, so I've added a id = serializers.IntegerField(required=False) on the serializer and put that id into the update_or_create method:
for obj in data:
Model.objects.update_or_create(
pk=obj.get('id', None), ...
)
django==3.0.5 django-filter==2.3.0 djongo==1.3.3 my database is mongodb
I have a simple model like below
class Parishioner(models.Model):
def _age(self):
return date.today().year - self.dob.year
"""Parishioner model"""
first_name = models.CharField(max_length=255)
last_name = models.CharField(max_length=255)
dob = models.DateField()
age = property(_age)
GENDER_CHOICES = [("Male", "Male"), ("Female", "Female"), ("Other", "Other")]
gender = models.CharField(max_length=10, choices=GENDER_CHOICES)
address = models.CharField(max_length=1000)
fathers_name = models.CharField(max_length=500)
mothers_name = models.CharField(max_length=500)
baptism_certificate = models.ImageField(null=True, upload_to=baptism_certificates_image_file_path)
marriage_certificate = models.ImageField(null=True, upload_to=marriage_certificates_image_file_path)
As you can see age is a calculated property.
I have my viewset like below
class ParishionerViewSet(viewsets.ModelViewSet):
queryset = Parishioner.objects.all()
serializer_class = serializers.ParishionerSerializer
authentication_classes = (TokenAuthentication,)
permission_classes = (IsAuthenticated,)
def get_queryset(self):
first_name = self.request.query_params.get('first_name')
last_name = self.request.query_params.get('last_name')
gender = self.request.query_params.get('gender')
address = self.request.query_params.get('address')
fathers_name = self.request.query_params.get('fathers_name')
mothers_name = self.request.query_params.get('mothers_name')
age = int(self.request.query_params.get('age'))
queryset = self.queryset
if first_name:
queryset = queryset.filter(first_name__contains=first_name)
if last_name:
queryset = queryset.filter(last_name__contains=last_name)
if gender:
queryset = queryset.filter(gender__contains=gender)
if address:
queryset = queryset.filter(address__contains=address)
if fathers_name:
queryset = queryset.filter(fathers_name__contains=fathers_name)
if mothers_name:
queryset = queryset.filter(mothers_name__contains=mothers_name)
if age:
queryset = queryset.filter(age__gte=age)
return queryset.filter()
All I want is to return obects who has age >= provides value.
So if I send a request to this url http://localhost:8000/api/parishioners/?age=32
I'm getting this error --> Cannot resolve keyword 'age' into field
So how can I use this url http://localhost:8000/api/parishioners/?age=32
and get objects who has age greater than or equal to 32 ?
You cannot use a function / property of the model in a query. You need to bring the logic of the function into the query instead.
from django.db.models.functions import ExtractYear, Now
queryset = queryset.annotate(age=ExtractYear(Now()) - ExtractYear('dob')).filter(age__gte=age)
How to combine many models in one query set so that it would be possible to use HyperlinkedModelSerializer using pagination?
I need to connect many models with the same fields.
That's what I did, but it doesn’t suit me.:
#models.py
class Merketing(models.Model):
question = models.CharField(max_length=500, unique=True)
answer = models.CharField(max_length=500)
class Management(models.Model):
question = models.CharField(max_length=500, unique=True)
answer = models.CharField(max_length=500)
#serializers.py
class MerketingSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Merketing
fields = ['id','question', 'answer']
class ManagementSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Management
fields = ['id','question', 'answer']
class FiltersSerializers(serializers.Serializer):
model_1 = MerketingSerializer(read_only=True,many=True)
model_2 = ManagementSerializer(read_only=True,many=True)
#viesw.py
class MerketingViewSet(viewsets.ModelViewSet):
queryset = Merketing.objects.all().order_by('question')
serializer_class = MerketingSerializer
permission_classes = [permissions.IsAuthenticated]
filter_backends = [filters.SearchFilter]
search_fields = ['question']
class ManagementViewSet(viewsets.ModelViewSet):
queryset = Management.objects.all().order_by('question')
serializer_class = ManagementSerializer
permission_classes = [permissions.IsAuthenticated]
filter_backends = [filters.SearchFilter]
search_fields = ['question']
class FiltersView(APIView):
def get(self, request, *args, **kwargs):
filters = {}
filters['model_1'] = Merketing.objects.all().order_by('question')
filters['model_2'] = Management.objects.all().order_by('question')
serializer = FiltersSerializers(filters)
return Response (serializer.data, status=HTTP_200_OK)
Here is the solution to my problem !!!
class Fi2ViewSet(viewsets.ModelViewSet):
qs1 = Merketing.objects.all()
qs2 = Management.objects.all()
qs3= Macroeconom.objects.all()
qs4 = Kse.objects.all()
queryset = qs1.union(qs2,qs3,qs4).order_by('question')
serializer_class = Fi2Serializer
permission_classes = [permissions.IsAuthenticated]
filter_backends = [filters.SearchFilter]
search_fields = ['question']
serializers.py
class Fi2Serializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Merketing
fields = ['id','question', 'answer']
I am trying to create order:
models.py:
class OrderItem(models.Model):
image_number = models.CharField(max_length=20)
title = models.CharField(max_length=20)
image_size = models.CharField(max_length=50)
file_type = models.CharField(max_length=20)
price = models.CharField(max_length=50)
def __str__(self):
return self.title
class Order(models.Model):
user = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
items = models.ManyToManyField(OrderItem)
start_date = models.DateTimeField(auto_now_add=True)
ordered_date = models.DateTimeField()
ordered = models.BooleanField(default=False)
def __str__(self):
return str(self.user)
serializers.py:
class AddtocartSerializers(serializers.ModelSerializer):
class Meta:
model = OrderItem
fields = ['image_number','title','image_size','file_type','price']
class CartSerializers(serializers.ModelSerializer):
class Meta:
model = Order
fields = ['item',
'start_date',
'ordered_date'
]
views.py:
class AddtocartView(viewsets.ModelViewSet):
authentication_classes = []
permission_classes = []
pagination_class = None
queryset=OrderItem
serializer_class = AddtocartSerializers
class CartView(viewsets.ModelViewSet):
authentication_classes = []
permission_classes = []
pagination_class = None
queryset=Order.objects.all()
serializer_class = CartSerializers
urls.py: api endpint
path('addtocart/',views.AddtocartView.as_view({'get':'list'}),name='addtocart'),
path('cart/',views.CartView.as_view({'get':'list'}),name='cart'),
I am confused here; should I create new order objects from serialzers or views?
You should override the created method on the AddtocartSerializers to add the order item to the order.
You can see more information about it here: https://www.django-rest-framework.org/api-guide/serializers/#writing-create-methods-for-nested-representations
here's my models:
class Recruteur(models.Model):
entrepriseName = models.CharField(max_length=50)
emplacement = models.CharField(max_length=50)
class Offre(models.Model):
title = models.CharField(max_length=100, blank=True, default=0)
idRecruteur = models.ForeignKey(Recruteur,verbose_name = "idRecruteur", on_delete=models.CASCADE, default=None)
and here's my api.py:
class VilleViewSet(ModelViewSet):
queryset = Offre.objects.values('idRecruteur__emplacement').distinct()
serializer_class = VilleSerializer
serializers.py:
class EmplacementSerializer(serializers.ModelSerializer):
class Meta:
model = Recruteur
fields = ('emplacement',)
class VilleSerializer(serializers.ModelSerializer):
emplacements = EmplacementSerializer(source='idRecruteur', read_only=True)
class Meta:
model = Offre
fields = ( 'emplacements',)
i was expecting a result like this
but i got nothing instead ..
Any ideas why?
You get nothing, because there is no emplacements field in Offre model. I guess, what you want is to get serialized Recruteur record, that is referenced by idRecruteur field. Try this:
class VilleSerializer(serializers.ModelSerializer):
idRecruteur = EmplacementSerializer(read_only=True)
class Meta:
model = Offre
fields = ( 'idRecruteur',)