I am trying to create functionality that allows a user to save items to a playlist and the user can have multiple playlists. Each item can be saved to multiple playlists as well. What is the best way to represent this data? Multiple tables with foreignkeys linking them or just 1 flat table?
multiple tables
class Playlist(models.Model):
playlist = models.CharField('Playlist', max_length = 2000, null=True, blank=True)
def __unicode__(self):
return self.playlist
class Video(models.Model):
video_url = models.URLField('Link to video', max_length = 200, null=True, blank=True)
video_tag = models.CharField('Video ID', max_length = 2000, null=True, blank=True)
def __unicode__(self):
return self.video_url
class UserPlaylist(models.Model):
profile = models.ForeignKey(User)
playlist = models.ForeignKey(Playlist)
def __unicode__(self):
return unicode(self.playlist)
class Videoplaylist(models.Model):
video = models.ForeignKey(Video)
playlist = models.ForeignKey(UserPlaylist)
def __unicode__(self):
return unicode(self.playlist)
1 table
class Everything(models.Model):
profile = models.ForeignKey(User)
playlist = models.CharField('Playlist', max_length = 2000, null=True, blank=True)
platform = models.CharField('Platform', max_length = 2000, null=True, blank=True)
video = models.CharField('VideoID', max_length = 2000, null=True, blank=True)
def __unicode__(self):
return u'%s %s %s %s' % (self.profile, self.playlist, self.platform, self.video)
There are two main relationships between the entities:
Playlist --> User, many to one
Video --> PlayList, many to many
Based on the above, you should arrange your data in a way like this:
class User():
name = CharField()
# other user info
class Video():
name = CharField()
# othter video info
class Playlist():
user = ForeigenKey(User)
name = CharField()
class PlaylistVideo():
plist = ForeigenKey(Playlist)
video = ForeigenKey(Video)
# When a user adds a video to one of his playlist
def add_video_to_playlist(user_name, playlist_name, video_name)
user = User.objects.get(name=user_name)
plist = Playlist.objects.get(user=user, name=playlist_name)
video = Video.objects.get(name=video_name)
plv = PlaylistVideo(plist=plist,video=video)
plv.save()
# To get the content of a user's some playlist:
def get_playlist_content(user_name, playlist_names):
user = User.objects.get(name=user_name)
plist = Playlist.objects.get(user=user, name=playlist_name)
return [plv.video for plv in PlaylistVideo.objects.filter(plist=plist)]
Related
My template is pulling the data I want it to from a related model, but it's also pulling <QuerySet [<XXXXX>]> where I only want it to display, in this case, the album title.
The Song model is as such
class Song(models.Model):
title = models.CharField(max_length=255)
playlist = models.ManyToManyField(Playlist)
in_queue = models.BooleanField()
is_playing = models.BooleanField()
album = models.ManyToManyField(Album)
keyword = models.ManyToManyField(Keyword)
audio_file = models.FileField()
lyrics = models.TextField()
p_graph = models.ManyToManyField(Album, related_name='phonograph')
and the Album class is as such
class Album(models.Model):
title = models.CharField(max_length=255)
artist = models.ManyToManyField(Artist)
year = models.IntegerField()
p_graph = models.CharField(max_length=255)
artwork = models.ImageField()
def __str__(self):
return self.title
Thanks
I have an application that has a dropdown menu among other things.
The menu is created based on the requirements. I wrote a query that checks the statuses and calculates how many requirements are in a given status. Then he builds a menu out of it. However, I have a problem because sometimes a requisition has been created but no items have been added to it. In that case, my menu shows this as one of the items. This is not what he expects. I would like the query to return and count only those requirements in a given status that have children.
Below I paste the model code and inquiries.
class D_DemandStatus(ModelBaseClass):
status = models.CharField(max_length=20, unique=True)
name = models.CharField(max_length=50)
created_user = models.ForeignKey(User, on_delete=models.PROTECT)
def save(self, *args, **kwargs):
user = get_current_user()
if user and not user.pk:
user = None
if not self.pk:
self.created_user = user
self.modified_by = user
super(D_DemandStatus, self).save(*args, **kwargs)
def __str__(self):
return self.name
class Meta:
verbose_name = 'Demand status'
verbose_name_plural = 'Demands status'
class Demand(models.Model):
name = models.CharField(max_length=500)
status = models.ForeignKey(D_DemandStatus, default=3, on_delete=models.PROTECT, )
insert_user = models.ForeignKey(User, on_delete=models.PROTECT, editable=False)
insert_date = models.DateTimeField(default=datetime.datetime.now, editable=False)
def save(self, *args, **kwargs):
user = get_current_user()
if user and not user.pk:
user = None
if not self.pk:
self.insert_user = user
self.status = D_DemandStatus.objects.get(status='PREPARED')
self.modified_by = user
super(Demand, self).save(*args, **kwargs)
def __str__(self):
return self.name
def submitt(self, *args, **kwargs):
if self.pk :
dict_status = D_DemandStatus.objects.get(status='WAITING')
print(dict_status)
self.demanddetails_set.filter(demand_id = self.pk).update(status=dict_status)
self.status = dict_status
self.save()
def status_actualize(self, *args, **kwargs):
if self.pk :
dict_status = D_DemandStatus.objects.get(status='ORDERED')
items_status = DemandDetails.objects.filter(demand=self.pk).values('status').distinct()
if len(items_status) == 1 and items_status[0]['status'] == dict_status.id :
self.status = D_DemandStatus.objects.get(status='ORDERED')
#elif len(items_status) > 1 :
# self.status = D_DemandStatus.objects.get(status='INPROGRESS')
self.save()
class Meta:
verbose_name = 'Demand'
verbose_name_plural = 'Demands'
class DemandDetails(models.Model):
demand = models.ForeignKey(Demand, on_delete=models.CASCADE, related_name='items')
component = models.ForeignKey(Component, on_delete=models.CASCADE)
order_item = models.ForeignKey(OrderItem, null=True, on_delete=models.PROTECT, editable=False, related_name='demand_details_item')
quantity = models.IntegerField(default=1)
comment = models.CharField(max_length=150, blank=True)
status = models.ForeignKey(D_DemandStatus, default=3, on_delete=models.PROTECT, )
insert_user = models.ForeignKey(User, on_delete=models.PROTECT, editable=False)
insert_date = models.DateTimeField(auto_now_add=True)
def quantityUpdate(self, val):
if self.pk :
self.quantity = val
self.save()
def save(self, *args, **kwargs):
user = get_current_user()
if user and not user.pk:
user = None
if not self.pk:
self.insert_user = user
self.status = D_DemandStatus.objects.get(status='PREPARED')
if not self.pk:
try:
super(DemandDetails, self).save(*args, **kwargs)
except IntegrityError as e:
obj = DemandDetails.objects.get(demand_id=self.demand_id, component_id=self.component_id)
obj.quantity = obj.quantity + 1
obj.save()
else:
super(DemandDetails, self).save(*args, **kwargs)
def __str__(self):
return self.demand.name
class Meta:
verbose_name = 'Demand detail'
verbose_name_plural = 'Demand details'
constraints = [
models.UniqueConstraint(fields=['demand_id', 'component_id'], name='epm - DemandDetail (demand, component)' )
]
The query that works now looks like this:
demand_list = Demand.objects.values('status__name', 'status__id', 'status__status').annotate(count=Count('status__name')).filter(Q(status__status='WAITING') | Q(status__status='PREPARED')).order_by('-status__name')
In this case, however, even if the demand is empty (no items added), it is counted as 1
So I have changed the code a little, but it doesn't work as I would like, because it also counts the individual elements of the demand - which is obvious, because the query returns the subsequent rows that are counted.
demand_list = Demand.objects.values('status__name', 'status__id', 'status__status').annotate(count=Count('status__name'), piece=Count('demanddetails')).filter(Q(piece__gte=1)).filter(Q(status__status='WAITING') | Q(status__status='PREPARED')).order_by('-status__name')
I need to write the query in such a way that I get a list of statuses with numbers of demands only which have derived elements in DemandDetails. If a Demand exists but has no derived elements then it is not taken into account - rather it is counted as 0. This is important because in the extreme case there may be only one Demand which is empty and then I want to have information about it in the menu but with the number 0.
I hope I have managed to write clearly what I chaie.
Please help me to create a suitable query.
Regards
models file
class Posting(models.Model):
company = models.CharField(max_length=250)
recruiter = models.CharField(max_length=250)
image = models.ImageField(upload_to='postings/%Y/%m/%d/', null=True)
description = models.TextField()
position_title = models.CharField(max_length=150)
## Based on LinkedIn
# Auto adds creation date
creation_date = models.DateTimeField(auto_now_add=True)
# If 0, unpaid; if more than 0, paid (can be used to diffrentiate in postings frontend)
pay_range = models.CharField(max_length=250)
location = models.CharField(max_length=1000)
# Number of current applicants (can be used to encourage people)
num_applicants = models.IntegerField(default=0)
def __str__(self):
return self.position_title
class Question(models.Model):
qTypes=[('T','text'),('TA','textarea'),('C','choice')]
question=models.CharField(max_length=10000)
type=models.CharField(max_length=10,choices=qTypes)
post=models.ForeignKey(Posting,on_delete=models.CASCADE)
choices=models.TextField(null=True,blank=True)
serializer
class QuestionSerializer(serializers.ModelSerializer):
class Meta:
model = Question
fields = ('id','type','question','post')
class PostingSerializer(serializers.ModelSerializer):
question=QuestionSerializer(many=False)
class Meta:
model = Posting
fields = ('id', 'company', 'recruiter', 'image', 'description', 'creation_date', 'pay_range', 'location', 'num_applicants', 'position_title','question')
i want to retrieve the post with it's questions like this i could retrieve the data of the question with its post but i dont want that
I am working on a post request in which the user chooses from a list of tags and makes combinations of tags. The combination of tags should then be posted. Nothing should get changed in the Tag table.
These are the models:
models.py
class Tag(models.Model):
name = models.CharField(max_length=256)
language = models.CharField(max_length=256)
objects = models.Manager()
def __str__(self):
"""Return a human readable representation of the model instance."""
return self.name or ''
#property
def tags(self):
tags = self.tagging.values('tag')
return tags.values('tag_id', 'tag__name', 'tag__language')
class Combination(models.Model):
user = models.ForeignKey(CustomUser, on_delete=models.SET_NULL, null=True)
gameround = models.ForeignKey(Gameround, on_delete=models.CASCADE, null=True)
resource = models.ForeignKey(Resource, on_delete=models.CASCADE, null=True)
tag_id = models.ManyToManyField(Tag, null=True)
created = models.DateTimeField(editable=False)
score = models.PositiveIntegerField(default=0)
objects = models.Manager()
def __str__(self):
return str(self.tag_id) or ''
This is the serializer for Combination.
serializers.py
class CombinationSerializer(serializers.ModelSerializer):
tag_id = TagWithIdSerializer(many=True, required=False, write_only=False)
resource_id = serializers.PrimaryKeyRelatedField(queryset=Resource.objects.all(),
required=True,
source='resource',
write_only=False)
gameround_id = serializers.PrimaryKeyRelatedField(queryset=Gameround.objects.all(),
required=False,
source='gameround',
write_only=False)
user_id = serializers.PrimaryKeyRelatedField(queryset=CustomUser.objects.all(),
required=False,
source='user',
write_only=False)
class Meta:
model = Combination
depth = 1
fields = ('id', 'user_id', 'gameround_id', 'resource_id', 'tag_id', 'created', 'score')
def create(self, validated_data):
user = None
request = self.context.get("request")
if request and hasattr(request, "user"):
user = request.user
score = 0
tag_data = validated_data.pop('tag_id', None)
combination = Combination(
user=user,
gameround=validated_data.get("gameround"),
resource=validated_data.get("resource"),
created=datetime.now(),
score=score
)
combination.save()
for tag_object in tag_data[0]:
combination.tag_id.add(tag_object)
return combination
def to_representation(self, instance):
rep = super().to_representation(instance)
rep['tag_id'] = TagWithIdSerializer(instance.tag_id.all(), many=True).data
return rep
I have tried posting the following JSON object to the database:
{
"gameround_id": 2015685170,
"resource_id": 327888,
"tag_id": [{"id": 2014077506, "name": "corwn","language": "en"}]
}
I am getting a ValueError: Field 'id' expected a number but got 'name'.
How can I fix this issue?
you need to provide tag id for each tag not all tag data,
Try like this
{
"gameround_id": 2015685170,
"resource_id": 327888,
"tag_id": [2014077506,2014077507]
}
I would like to make a Ingredientslist for recipies(model named articles) and therefore need to assign unique values to Ingredients out of a Many to Many Infredient list.
I know that there is no straight forward way to implement a two dimensional array in django but I hope someone here has had this issue and knows a workaround.
Here I have my models being part of this issue:
class Ingredient(models.Model):
name = models.CharField(max_length=200, null=False)
kcal = models.IntegerField(validators=[MinValueValidator(0), MaxValueValidator(800)], blank=True, default=0)
carbs = models.IntegerField(validators=[MinValueValidator(0), MaxValueValidator(99)], blank=True, default=0)
protein = models.IntegerField(validators=[MinValueValidator(0), MaxValueValidator(99)], blank=True, default=0)
fat = models.IntegerField(validators=[MinValueValidator(0), MaxValueValidator(99)], blank=True, default=0)
class Article(models.Model):
banner = models.ImageField(null=True, default='dashboard-BG.jpg')
headline = models.CharField(max_length=200, null=False, default='Unnamed')
subtitle = models.CharField(max_length=300, null=False, default='Unnamed')
article_body = models.CharField(max_length=4000, null=False, default='Lorem Ipsum')
date_created = models.DateTimeField(auto_now_add=True)
ingredientList = models.BooleanField(null=True, default=False)
ingredients = models.ManyToManyField(Ingredient, blank=True)
kcal = models.IntegerField(validators=[MinValueValidator(0), MaxValueValidator(3000)], null=True, blank=True)
carbs = models.IntegerField(validators=[MinValueValidator(0), MaxValueValidator(3000)], null=True, blank=True)
protein = models.IntegerField(validators=[MinValueValidator(0), MaxValueValidator(3000)], null=True, blank=True)
fat = models.IntegerField(validators=[MinValueValidator(0), MaxValueValidator(3000)], null=True, blank=True)
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
ingredients = self.ingredients
totalCalories = 0
totalCarbs = 0
totalProtein = 0
totalFat = 0
for i in ingredients:
totalCalories += i.kcal
totalCarbs += i.carbs
totalProtein += i.protein
totalFat += i.fat
if i == 0:
return
self.kcal = totalCalories
self.carbs = totalCarbs
self.protein = totalProtein
self.fat = totalFat
self.save()
def __str__(self):
return self.headline
The 'two dimensional array should be the ingredients model field. Many ingredients having a specific unique amount for this recipe.
Thx for all the answers in advance ;)
In Django, models are representations of fields in SQL datatables. You could look into the JSONField type. This Field will hold any form of JSON data, basically a python dictionary. You could have one key for the ingredient and one key for the amount. Hope this helps!