How to process data from one model field to another - python

I have models of Exercise, Training and Workout.
Training contains some exercises (Exercise)
Workout contains trainings (Training).
Snippet of my models.py:
class Exercise(models.Model):
user = models.ForeignKey(User, related_name='exercises',
on_delete=models.CASCADE)
name = models.CharField(max_length=80)
description = models.TextField(max_length=300)
details = models.ManyToManyField(ExerciseDetail, blank=True)
...
class Training(models.Model):
user = models.ForeignKey(User, related_name='trainings',
on_delete=models.CASCADE)
name = models.CharField(max_length=80)
description = models.CharField(max_length=250)
exercises = models.ManyToManyField(Exercise, related_name='trainings',
blank=True)
...
class Workout(models.Model):
user = models.ForeignKey(User, related_name='workouts',
on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now=True)
name = models.CharField(max_length=200)
description = models.TextField(max_length=400, blank=True)
trainings = models.ManyToManyField(Training, related_name='workouts',
blank=True)
...
I would like to have possibility to use something like Workout.objects.get(name='workout').exercises.objects.all() to get a list/set of all exercises included in trainings of chosen Workout.
I would also like to have possibility to use exercises`` field with Django Rest Framework to list all exercises, possibly with link to particularExercise``` model serializer.
Can someone give a hint how can I do that?

You can query this with:
Exercise.objects.filter(
trainings__workouts__name='workout'
)
With the consecutive underscores (__), you thus can look "through" relations.
This will thus return the Exercises that belong to Trainings that belong to Workouts with as name 'Workout'.

Related

How to get the most liked users in django rest-api

So I have a social media app, where users can like the posts of other users. Now I want to fetch the top 20 users who have received the most number of likes. I am pretty much confused how to query my Likes Model
My LIKES MODEL
class PostLike(models.Model):
user_who_liked = models.ForeignKey(User, on_delete=models.CASCADE)
post_liked = models.ForeignKey(Post, on_delete=models.CASCADE)
liked_on = models.DateTimeField(default=timezone.now)
SIMPLIFIED POST MODEL
class Post(models.Model):
id = models.AutoField(primary_key=True)
user = models.ForeignKey(User, on_delete=models.CASCADE)
caption = models.TextField()
date = models.DateTimeField(default=timezone.now)
likes = models.ManyToManyField(
User, blank=True, through=PostLike)
image = models.TextField()
class Meta:
ordering = ['-id']
SIMPLIFIED USER MODEL
class User(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(unique=True)
user_name = models.CharField(max_length=100, unique=True)
date = models.DateTimeField(default=timezone.now)
profile_picture = models.TextField(
default="https://www.kindpng.com/picc/m/24-248253_user-profile-default-image-png-clipart-png-download.png")
bio = models.CharField(max_length=200, default="")
objects = CustomManger()
def __str__(self):
return self.user_name
** My View **
#api_view(["GET"])
#permission_classes([IsAuthenticated])
def leaderboard(request):
# I dont know how to query the PostLike model now to get the most liked users
pass
First I changed the user attribute in your Post model, I added related_name because otherwise the related names were clashing. This is the definition I used, otherwise your models are unchanged.
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='author')
I.e. the posts by a user are accessible on User via the author attribute.
The following query gives you the top 20 users by number of likes they received:
User.objects.annotate(num_likes=Count('author__likes')).order_by('-num_likes')[:20]
Explanation:
Query User model and
annotate each user by doing a count:
author leads to the posts by the user
likes follows to PostLike and counts all likes which are associated with a post by the user
then order by number of likes descending,
and limit the number of retrieved objects to 20.

Django - ManyToMany relationship not unique

So the case is :
I have a Course model with a manytomany relationship to a student model .
The course also have a one to many relationship with a Module model, so a course have many modules but each module belongs to one course .
On my Module i specified a boolean field named completed to be able to calculate how much modules of that course did the student complete .
The main problem is :
When a module is completed by a student, it's marked as completed forever.
In other words, when another user enrolls in the same course , he will find the completetion state of the modules as left by the other user .
I want each modules to be initialized when a student enrolls in a course , but also want to them to be saved just for that student without saving the changes globally, it's like making an initialized copy of the course whenever a new user enrolls in it, and save his records on this copy not on the actual Course model in the database .
Thanks and here's the code :
class Student(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, null=True, blank=True)
full_name = models.CharField(max_length=200, null=True, blank=True)
age = models.PositiveIntegerField(null=True, blank=True)
email = models.CharField(max_length=200, null=True, blank=True)
phone = models.CharField(max_length=20, null=True, blank=True)
about = models.TextField(null=True, blank=True)
date_joined = models.DateTimeField(auto_now_add=False, null=True, blank=True)
class Course(models.Model):
owner = models.ForeignKey(User, related_name='courses_created',help_text=_('owner') ,on_delete=models.CASCADE)
subject = models.ForeignKey(Subject, related_name='courses',help_text=_('subject') ,on_delete=models.CASCADE)
title = models.CharField(max_length=200,help_text=_('title'))
slug = models.SlugField(max_length=200, help_text=_('slug') ,unique=True, allow_unicode=True)
overview = models.TextField(help_text=_('overview'))
created = models.DateTimeField(auto_now_add=True)
thumbnail = models.ImageField(upload_to='images', null=True, blank=True)
students = models.ManyToManyField(Student, related_name='courses_joined',help_text=_('students'), blank=True)
def completion_rate(self):
sum = 0
for m in self.modules.all():
if m.completed:
sum +=1
rate = int((sum / self.modules.count()) * 100)
return rate
class Module(models.Model):
course = models.ForeignKey(Course, related_name='modules',help_text=_('course') ,on_delete=models.CASCADE)
title = models.CharField(max_length=200 )
description = models.TextField(blank=True)
order = OrderField(blank=True, for_fields=['course'])
completed = models.BooleanField(default=False, null=True)
and the view that completes a module :
def complete(request, m_id, c_id):
mod = get_object_or_404(Module, id=m_id)
course = get_object_or_404(Course, id=c_id)
mod.completed = True
mod.save()
return redirect('student_course_detail_module', course.id ,mod.id)
This is a logic problem. You are adding a boolean field to the module which once set by a single student will remain set for all other students logging in.
The solution to this is to restructure the model.
Remove the completed boolean field from the module model.
Create another model completed_modules which will have a one-to-one field with student, one-to-one field with course, and a one-to-one field with module as such:
class CompletedModules(models.Model):
module = models. ForeignKey(Module, on_delete=models.CASCADE)
course = models.ForeignKey(Course, on_delete=models.CASCADE)
user = models.ForeignKey(Student, on_delete=models.CASCADE)
When a given student completes a given module for a given course, you simply records that in this table
You will need to rewrite your completed function to effect this insert operation

How can I organize a database with products and users?

I am currently trying to organize a django database model for an online shop-system with users and products.
My code:
class UserData(models.Model):
username = models.CharField(max_length=100)
password = models.CharField(max_length=500)
bought_products = models.ForeignKey(MarketProducts, on_delete=models.CASCADE)
class VendorData(models.Model):
username = models.CharField(max_length=100)
password = models.CharField(max_length=500)
sold_products = models.ForeignKey(MarketProducts, on_delete=models.CASCADE)
class MarketProducts(models.Model):
category = models.CharField(max_length=100)
vendor = models.ForeignKey(VendorData, on_delete=models.CASCADE)
name = models.CharField(max_length=200)
description = models.CharField(max_length=1000)
price = models.IntegerField()
pub_date = models.DateTimeField('Date published')
image = models.ImageField(upload_to=b'shop/media/images/')
likes = models.IntegerField()
dislikes = models.IntegerField()
How can I organize a good working system so all the products a user bought are saved inside the bought_products column and all the products a vendor sold can be saved inside the sold_products column. Do I have to use a ForeignKey for that or is there something more suitable for this situation? Also, if there is anything unwise about the existing structure of the database model (for example the current image field column only saves the link but not the image itself which is kinda weird...), please feel free to correct me :).
Many thanks in advance :D
In this case I suggest to make bought_products and sold_products instances of ManyToManyField because the same product can be bought by multiple Users and sold by multiple vendors
Firstly I would start by reading the following documentation on django auth customization. Seems like that would help you out a little bit.
https://docs.djangoproject.com/en/2.2/topics/auth/customizing/
Additionally, I think you need to better evaluate your data modelling to make each model more explicit/clearly defined. See example below:
class Products(models.Model):
vendor = models.ForeignKey(VendorData, on_delete=models.CASCADE)
name = models.CharField(max_length=200)
description = models.CharField(max_length=1000)
price = models.IntegerField()
pub_date = models.DateTimeField('Date published')
image = models.ImageField(upload_to=b'shop/media/images/')
likes = models.IntegerField()
dislikes = models.IntegerField()
class Category(models.Model):
name = models.CharField(max_length=100)
description = models.CharField(max_length=100)
active = models.BooleanField(default=True)
class ProductCategory(models.Model):
product = models.ForeignKey(Products, on_delete=models.CASCADE)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
creation_date = models.DateTimeField(auto_add_now=True)
From there I would construct a separate model which would store the customer purchased items. Since you already have a model which stores the vendor to product data, you shouldn't need anything additional to identify how many sales a particular vendor has.

How to build a form that contains items of a collection

I have 2 models: a wishlist model and a wish model. A wishlist is made of n wish (wish have a reference to his wishlist). I would like update a wishlist with a form. Here is the form I'd like to have:
input:text wishlist.name
for wish in wishlist:
input:text wish.name
input:number wish.price
I'm new to django and don't know how to build a form that handle two models.
# models.py
class WishList(models.Model):
name = models.CharField(max_length=200)
owner = models.ForeignKey(User, on_delete=models.CASCADE)
created_date = models.DateTimeField('date of creation')
class Wish(models.Model):
name = models.CharField(max_length=200)
price = models.DecimalField(max_digits=24, decimal_places=2)
description = models.TextField(max_length=200)
wishlist = models.ForeignKey(WishList, on_delete=models.CASCADE)

Fetching model instance from a multiple direct relationship

Can anyone help me fetch data from this model structure? because i have a hard time doin this for hours now.
First I would like to get all distinct SubSpecialization from all Doctor which has a given Specialization.title
Secondly I would like to get all Doctor which has a specific Specialization.title and has no SubSpecialization.
Here is the Doctor model
class Doctor(models.Model):
name = models.CharField(max_length=50)
room_no = models.IntegerField()
floor_no = models.IntegerField()
contact_no = models.CharField(max_length=50, blank=True, null=True)
notes = models.CharField(max_length=70, blank=True, null=True)
This is the model Doctor relationship is connected to Specializationand SubSpecialization.
class DoctorSpecialization(models.Model):
doc = models.ForeignKey(Doctor, models.DO_NOTHING)
spec = models.ForeignKey('Specialization', models.DO_NOTHING)
class DoctorSubSpecialization(models.Model):
doc = models.ForeignKey(Doctor, models.DO_NOTHING)
sub_spec = models.ForeignKey('SubSpecialization', models.DO_NOTHING)
This is where i would make a criteria.
class Specialization(models.Model):
title = models.CharField(unique=True, max_length=45)
point = models.IntegerField()
class SubSpecialization(models.Model):
title = models.CharField(max_length=100)
There is no direct relationship between the Specialization and SubSpecialization please help.
Firstly, your specialization and subspecialization are both many-to-many relationships with Doctor. You should declare that explicitly, and drop those intervening models unless you need to store other information on them.
class Doctor(models.Model):
...
specializations = models.ManyToManyField('Specialization')
subspecializations = models.ManyToManyField('SubSpecialization')
Now you can query for all the subspecializations for doctors who have a specific specialization:
SubSpecialization.objects.filter(doctor__specialization__title='My Specialization')
Your second query doesn't make sense given the fact there is no relationship between specialization and subspecialization, you'll need to clarify what you mean by "no subspecialization in a specific specialization".
Edit
To find doctors who have a specific Specialization and then no subspecializations at all:
Doctor.objects.filter(specialization__name="My Specialization",
subspecialization=None)

Categories