I am trying to get the average with respect to the months of data in DRF. I have two problems here my values in the string so I need to convert first into double and then calculate it. I am not able to think any solution that's why posting the question without my solution what I have tried.
My modal class is:
class FeedDataValues(models.Model):
sensor = models.ForeignKey(
'core.SensorDevice',
on_delete=models.SET_NULL,
null=True
)
hardware_id = models.CharField(max_length=255)
field1 = models.CharField(max_length=255, null=True)
field2 = models.CharField(max_length=255, null=True)
field3 = models.CharField(max_length=255, null=True)
received_at = models.DateTimeField(null=True)
My serializer class is:
class MQTTFeedDataSerializer(serializers.ModelSerializer):
class Meta:
model = models.FeedDataValues
fields = ('id','sensor','hardware_id','field1','field2','received_at',)
And views is:
class MQTTFeedDataListView(generics.ListAPIView):
authentication_classes = (authentication.TokenAuthentication,)
permission_classes = (permissions.IsAuthenticated, permissions.IsAdminUser,)
serializer_class = serializers.MQTTFeedDataSerializer
queryset = models.FeedDataValues.objects.all()
filter_backends = (DjangoFilterBackend, OrderingFilter,)
filter_class = filters.MQTTFeedValuesFilter
Any suggestion will be of great help.
Related
I'm doing a cookbook app, which help users find meal thay can do with their ingridients. I'm using Django RestFramework, and i need to return list of avaliable meals that user can do, but don't know how to do search by ingridients
My models.py:
#models.py
class Meal(models.Model):
name = models.CharField(max_length=250)
description = models.TextField(blank=True, null=True)
recipe = models.TextField()
is_published = models.BooleanField(default=False)
category = ForeignKey('Category', on_delete=models.CASCADE, null=True)
user = ForeignKey(User, verbose_name='User', on_delete= models.CASCADE)
difficulty = ForeignKey('Difficulty', on_delete=models.PROTECT, null=True)
ingridients = models.ManyToManyField('Ingridient')
class Ingridient(models.Model):
name = models.CharField(max_length=100, db_index=True)
ico = models.ImageField(upload_to="photos/%Y/%m/%d/", blank=True, null=True)
category = ForeignKey('CategoryIngridients', on_delete=models.CASCADE, null=True)
def __str__(self):
return self.name
class CookBookUser(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
ingridients = models.ManyToManyField('Ingridient')
serializer.py
class MealSerializer(serializers.ModelSerializer):
class Meta:
model = Meal
fields = "__all__"
views.py
class CraftWithUsersIngridientsListAPIView(generics.ListAPIView):
serializer_class = MealSerializer
def get_queryset(self):
return Meal.objects.filter(ingridients=CookBookUser.objects.filter(user_id = self.request.user.id).ingridients)
CraftWithUsersIngridientsListAPIView isn't working and I get AttributeError 'QuerySet' object has no attribute 'ingridients', can someone help fix this?
I tried building different serializer but it doesn't help
class CraftWithUsersIngridientsListAPIView(generics.ListAPIView):
serializer_class = MealSerializer
def get_queryset(self):
user_ingredients = CookBookUser.objects.get(user=self.request.user).ingredients.all()
return Meal.objects.filter(ingredients__in=user_ingredients)
This way, you first get the CookBookUser instance for the current user, then get all of their ingredients, and finally, filter the Meal objects that contain those ingredients. The __in query lookup is used to check if the meal ingredients are in the user's ingredients.
I've created a model of analysis types and then I created a table that groups several analyses into one group:
class AnalysisType(models.Model):
a_name = models.CharField(max_length=16,primary_key=True)
a_measur = models.CharField(max_length=16)
a_ref_min = models.DecimalField(max_digits=5, decimal_places=2, null=True, blank=True)
a_ref_max = models.DecimalField(max_digits=5, decimal_places=2, null=True, blank=True)
# analysis_group = models.ForeignKey(AnalysysGroup, on_delete=models.CASCADE, default=1)
def __str__(self):
return f"{self.a_name} - {self.a_measur}"
class AnalysysGroup(models.Model):
group_name = models.CharField(max_length=32)
analysis = models.ManyToManyField(AnalysisType, blank=True)
def __str__(self):
return f"{self.group_name}"
I want to have the option to multiply add values via the admin panel (I.E. I chose Analysis type then below appear fields to fill)
class PatientGroupAnalysis(models.Model):
patient = models.ForeignKey(Patient, on_delete=models.CASCADE)
analysis_date = models.DateTimeField()
analysis_type = models.ForeignKey(AnalysysGroup, on_delete=models.CASCADE, default=1)
# amalysis_data = ???
def __str__(self):
return f"{self.patient}: {self.analysis_date} - {self.analysis_type} - {self.analysis_data}"
I tried to use analysis_data = analysis.type.objects.all() and etc. but that's the wrong way.
Try this:
Admin panel with StackedInline
from django.contrib import admin
from .models import AnalysisType, PatientGroupAnalysis
# Register your models here.
class PatientGroupAnalysisInline(admin.StackedInline):
model = PatientGroupAnalysis
#admin.register(AnalysisType)
class AnalysisTypeAdmin(admin.ModelAdmin):
list_display = ["id", "a_name", "a_measur", "a_ref_min", "a_ref_max"]
search_fields = ("id", "a_name")
inlines = [PatientGroupAnalysisInline]
Am having this kind of a Model, and I wanted to order by blog_views property, how best can this be done.
This is the model :
class Post(TimeStampedModel, models.Model):
"""Post model."""
title = models.CharField(_('Title'), max_length=100, blank=False,
null=False)
# TODO: Add image upload.
image = models.ImageField(_('Image'), upload_to='blog_images', null=True,
max_length=900)
body = models.TextField(_('Body'), blank=False)
description = models.CharField(_('Description'), max_length=400,
blank=True, null=True)
slug = models.SlugField(default=uuid.uuid4(), unique=True, max_length=100)
owner = models.ForeignKey(User, related_name='posts',
on_delete=models.CASCADE)
bookmarks = models.ManyToManyField(User, related_name='bookmarks',
default=None, blank=True)
address_views = models.ManyToManyField(CustomIPAddress,
related_name='address_views',
default=None, blank=True)
likes = models.ManyToManyField(User, related_name='likes', default=None,
blank=True,
)
class Meta:
ordering = ['-created']
def __str__(self):
"""
Returns a string representation of the blog post.
"""
return f'{self.title} {self.owner}'
#property
def blog_views(self):
"""Get blog post views."""
return self.address_views.all().count()
I read about annotate but couldn't get a clear picture, how can I formulate this in my view.
class PostList(generics.ListCreateAPIView):
"""Blog post lists"""
queryset = Post.objects.all()
serializer_class = serializers.PostSerializer
authentication_classes = (JWTAuthentication,)
permission_classes = (PostsProtectOrReadOnly, IsMentorOnly)
filter_backends = [filters.SearchFilter, filters.OrderingFilter]
search_fields = ['title', 'body',
'tags__name', 'owner__email',
'owner__username'
]
I want to filter by a property in the URL
You can't order by a method field because the ordering is done at the database level, and the database has no idea that, that field exists.
But you can use annotate like so:
from django.db.models import Count
class PostList(generics.ListCreateAPIView):
...
queryset = Post.objects.annotate(address_views_count=Count('address_views')).order_by('address_views_count')
If you want the ordering to be optional you can use filter_queryset:
class PostList(generics.ListCreateAPIView):
def filter_queryset(self, request, queryset, view):
ordering = self.request.GET.get("ordering", None)
if ordering == 'blog_views':
queryset = queryset.annotate(address_views_count=Count('address_views')).order_by('address_views_count')
return queryset
for example I have 3 classes defined as such
class Timecard(models.Model):
site_code = models.CharField(max_length=200)
contractor_name = models.CharField(max_length=200)
approved = models.BooleanField(default=False)
date = models.DateTimeField(default=timezone.now)
class Job(models.Model):
job_code = models.CharField(max_length=200)
description = models.CharField(max_length=200)
hourly_rate = models.DecimalField(max_digits=10, decimal_places=2)
max_hours = models.PositiveIntegerField()
time_card = models.ManyToManyField(Timecard, through="Timecard_Job")
class Timecard_Job(models.Model):
time_card = models.ForeignKey(Timecard, on_delete=models.CASCADE)
job = models.ForeignKey(Job, on_delete=models.CASCADE)
hours_worked = models.DecimalField(max_digits=10, decimal_places=2)
I have the following class governing my view
class FillTimecard(CreateView):
model = Timecard
form_class = CreateTimeCardForm
template_name = 'timesheet/timesheetSubmit.html'
success_url = reverse_lazy("index")
finally I have the following form class
class CreateTimeCardForm(forms.ModelForm):
class Meta:
model = Timecard
fields = ['site_code', 'contractor_name', 'date','job']
job = forms.ModelMultipleChoiceField(
queryset=Job.objects.all(),
widget=forms.Select
)
When I select the job from the drop down I want to also be able to enter the hours worked on that specific job and that be inserted into the join table.
If someone can just provide resources that will help me achieve this it would be appreciated.
Similar to what you have done with the job field, a new field can be added to your form as the docs explain here.
Essentially:
class CreateTimeCardForm(forms.ModelForm):
job = forms.ModelMultipleChoiceField(
queryset=Job.objects.all(),
widget=forms.Select
)
hours_worked = forms.DecimalField(label="Hours worked", min_value=0, decimal_places=2)
class Meta:
model = Timecard
fields = ['site_code', 'contractor_name', 'date']
Then you should implement clean() and save() methods in CreateTimeCardForm to be sure that the data is valid and to create the associations with other models, saving hours_worked.
Note: IF INFORMATION BELOW IS NOT CLEAR TO UNDERSTAND - PLEASE ASK ME, I WILL UPDATE AND POST INFORMATION YOU NEED | It is important for me
In Warehouse(models.Model) I have amount attribute and
in ChosenProduct(models.Model) - quantity
I'm trying to get amount in Warehouse through chosen_products instance in App_formSerializer to add the quantity of chosen_product
But I can not get the chosen_products objects from instance
--> below Out:
class WarehouseSerializer(serializers.ModelSerializer):
category_name = serializers.ReadOnlyField(
source='category_product.category_name')
posted_user = serializers.ReadOnlyField(
source='posted_user.username')
class Meta:
model = Warehouse
fields = ['id', 'category_product', 'category_name', 'condition',
'product_name', 'amount', 'barcode', 'f_price', 'created_at', 'updated_at', 'posted_user']
class ChosenProductSerializer(serializers.ModelSerializer):
product_info = WarehouseSerializer(source='product', read_only=True)
period_info = Product_periodSerializer(source='period', read_only=True)
class Meta:
model = ChosenProduct
exclude = ('app_form',)
class App_formSerializer(serializers.ModelSerializer):
chosen_products = ChosenProductSerializer(many=True)
def update(self, instance, validated_data):
instance.terminated = validated_data.get('terminated', instance.terminated)
if instance.terminated == True :
print('-----------TRUE--------------------')
print(instance.chosen_products)
print('-----------PRINT--------------------')
instance.save()
return instance
class Meta:
model = App_form
fields = '__all__'
Out
-----------TRUE--------------------
creditapi.ChosenProduct.None
-----------PRINT--------------------
QUESTION UPDATED
models.py
class Warehouse(models.Model):
category_product = models.ForeignKey(
Category_product, on_delete=models.CASCADE)
product_name = models.CharField(max_length=200, unique=True)
condition = models.BooleanField(default=False)
amount = models.IntegerField()
barcode = models.BigIntegerField()
f_price = models.CharField(max_length=255, null=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
posted_user = models.ForeignKey(User, on_delete=models.CASCADE, default=1)
def __str__(self):
return self.product_name
class App_form(models.Model):
phone_regex = RegexValidator(regex=r'^\+?1?\d{9,12}$', message="Phone number must be entered in the format: '998981234567'. Up to 12 digits allowed.")
terminated = models.BooleanField(default=False)
name = models.CharField(max_length=150)
phone_number = models.CharField(validators=[phone_regex], max_length=13)
def __str__(self):
return self.surname
class ChosenProduct(models.Model):
product = models.ForeignKey(Warehouse, on_delete=models.CASCADE)
quantity = models.IntegerField()
app_form = models.ForeignKey(App_form, on_delete=models.CASCADE, related_name='chosen_products')
def __str__(self):
return self.product.product_name
If you write instance.chose_products you access the manager, not the QuerySet that contains the items. You can use .all() to obtain the QuerySet with all the objects:
print(instance.chosen_products.all())
If you access a ForeignKey in reverse, you have a manager, since zero, one, or more elements can refer to the instance.
You can for example aggregate over the chose_products, for example if you want to retrieve the number of related chose_products, you can use:
print(instance.chosen_products.count())
I would however advise not store (aggregated) data in the App_form, but aggregate data when you need it. Data duplication is an anti-pattern, and it turns out it is hard to keep data in sync.