I just started with django and I want to make a spotify clone. I want to make it so then when you click on an album it shows the songs for that album.
this is my models.py
from django.db import models
class album(models.Model):
title = models.CharField(max_length=50)
artist = models.IntegerField()
genre = models.CharField(max_length=20)
id = models.AutoField(primary_key=True)
artwork = models.CharField(max_length=1000)
class artist(models.Model):
name = models.CharField(max_length=50)
id = models.AutoField(primary_key=True)
class song(models.Model):
name = models.CharField(max_length=60)
artist = models.IntegerField()
album = models.IntegerField()
id = models.AutoField(primary_key=True)
This is my views.py
from django.shortcuts import render
from .models import album, song
def home(request):
context = {
'albums': album.objects.all(),
}
return render(request, 'main/index.html', context)
For that particular album for which the button is clicked, or all albums, please clarify your question.
Well, it cane achieved through frontend using dropdowns and much more components, or simply redirecting to another page which will show relevant albums.
Through django, if you need to see all albums so you are doing correct.
But if you see a particular album by clicking, so you have to pass that album's id or name or you can pass anything which is unique.
urls.py
path('particular-album/<int:id>/,views.particular_album,name='particular')
Html file
{% for album in albums %}
see particular album
Views.py
def particular_album(req,id):
one_album=album.objects.get(id=id)
return render(req,"main/particular.html",{'one':one_album})
Then in your template file without running the loop you can get all the properties of this object.
If there are more than one objects, so you can use album.objects.filter(field_name=variable) same as like one object, but it gives you more than one, and the variable you have to pass must not be associated with unique constraint.So, it gives you all objects which belong to particular category.Then, you have to run loop in your template file.
Related
I am working on a product overview page in Django.
For this I have three models: category, brand, product.
I have created a View with ListView of the category. I loop through them to display them. I then want to open another overview of all brands within that category.
How do I do this?
Here are my models:
class Category(models.Model):
category_name = models.CharField(max_length=200)
sub_category = models.CharField(max_length=200,blank=True,null=True)
category_picture = models.ImageField(upload_to='category/', null=True, blank=True)
def __str__(self):
if self.sub_category is None:
return self.category_name
else:
return f" {self.category_name} {self.sub_category}"
class Meta:
ordering = ['category_name']
class Brand(models.Model):
category = models.ForeignKey('Category', on_delete=models.SET_NULL,null=True,blank=True)
brand_name = models.CharField(max_length=200)
brand_owner = models.CharField(max_length=200)
brand_story = models.TextField()
brand_country = models.CharField(max_length=200)
def __str__(self):
return f"{self.brand_name}"
class Bottle(models.Model):
category_name = models.ForeignKey('Category', on_delete=models.SET_NULL,null=True,blank=True)
brand = models.ForeignKey('Brand', on_delete=models.CASCADE)
bottle_name = models.CharField(max_length=255)
bottle_info = models.TextField()
bottle_tasting_notes = models.TextField()
bottle_barcode = models.IntegerField()
bottle_image = models.ImageField(upload_to='bottles/',null=True)
def __str__(self):
return f"{self.brand.brand_name} {self.bottle_name}"
How do I open a listview of all brands within a certain category from a link of the category listview?
First thing is to create another listview that displays all brands within a specific category. We do this by creating a new get_queryset() method.
views.py
class BrandListView(ListView):
model = Brand
def get_queryset(self):
return Brand.objects.filter(category__category_name=self.kwargs['category'])
Next add a url to your URLS.py so it can be accessed. We're using category_name as part of the url so it's human readable
from .views import BrandListView
urlpatterns = [
path('brands/<str:category>/', PublisherBookList.as_view()), name= "brand_list"
]
Then, as you loop through your categories in your template, create a link to the url
{% for category in categories %}
{{category.category_name}} : See brands in category
{% endfor %}
This will work as long as your categories have fairly simple names. If not, you might want to use the ID in the URL instead, or add a slug field to the model and use that.
I'm trying to make a Django website which has all products with all their details(each product has it's own page). However, since there are too many products and they keep changing, I want to automate the creation and deletion of pages according to the database model (models.py).
Am I supposed to use a class based view? Am I supposed to use a function based view with a loop in it?
# models.py
import uuid
from django.db import models
class Brand(models.Model):
brand_id = models.AutoField(primary_key=True, unique=True)
brand_name = models.CharField(max_length=100, unique=True)
class Product(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
name = models.CharField(max_length=100, null=False, blank=False)
brand_id = models.ForeignKey(Brand)
# A lot more columns will follow (didn't lock on them yet)
# This is what I had thought of initially
If I understand what you are trying to do (create product pages automatically), you can override the save method in your Products model to create a new Page each time a Product is added, and then use models.CASCADE in the foreign key so that if a product is deleted, the associated page is deleted, like so:
from django.utils.text import slugify
class Page(models.Model):
product = models.ForeignKey('Product', on_delete=models.CASCADE)
...
class Product(models.Model):
name = models.CharField(max_length=255)
slug = models.SlugField(blank=True, null=True)
...
def save(self, *args, **kwargs):
self.slug = slugify(instance.name)
page = Page.objects.create(product=self,...)
page.save()
super(GeeksModel, self).save(*args, **kwargs)
You can also use Django signals, like so in your models.py file:
#receiver(post_save, sender=Product)
def create_product_page(sender, instance, created, **kwargs):
if created:
instance.slug = slugify(instance.name)
page = Page.objects.create(product=instance,...)
page.save()
instance.save()
In your views.py, for example, to get a page:
def product_page(request, product_id, product_slug):
page = Page.objects.get(product__id=product_id)
...
context = {
'page_data': page
}
return render(request, 'page_template.html', context)
And in your urls.py for the custom product pages:
...
path('/products/pages/<int:product_id>/<str:product_slug>/', product_page, name="product_page")
...
So the url would look like:
http://example.com/products/pages/3/my-amazing-widget/
If you created the link dynamically in a template with something like:
{% for product in products %}
<p><a href='{% url 'product_page' product.id product.slug %}'>{{ product.name }}</a></p>
{% endfor %}
And there are other ways as well. In the model example above, I included a SlugField you can use to generate the custom URL as well. If you elaborate on your question I can update my answer.
I have a Django Rest Framework project, users can post,comment any post and like any post. I can't figure it out the logic in models.py
from django.db import models
from django.contrib.auth.models import User
class Post(models.Model):
title = models.CharField(max_length=100)
body = models.CharField(max_length=100)
post_author = models.ForeignKey(User,on_delete=models.CASCADE,related_name='posts')
def __str__(self):
return self.title
class Comment(models.Model):
body=models.CharField(max_length=100)
commet_post = models.ForeignKey(Post,on_delete=models.CASCADE,related_name='comments')
comment_author = models.ForeignKey(User,on_delete=models.CASCADE)
def __str__(self):
return self.body
class Like(models.Model):
like_post = models.ForeignKey(Post,on_delete=models.CASCADE)
like_author=models.ForeignKey(User,on_delete=models.CASCADE)
created = models.DateTimeField(auto_now_add=True)
You could make two endpoints for like: 1) for create & 2) for delete. Whenever someone clicks on the like button, it will hit the create endpoint and create a Like object. When someone clicks on unlike, it will hit the delete endpoint and delete the object. Like model will have a one-to-one relationship with User and Post model. You can count likes by a query such as: Like.objects.filter(like_post=post.id).aggregate(Count('pk'))
I don`t know this the right title to ask. And i have not enough reputation to post image.
models.py
class Artist(models.Model):
artist_name = models.CharField(max_length=100)
class Album(models.Model):
album_name = models.CharField(max_length=100)
artist = models.ForeignKey(Artist)
And i registered models to admin
in the admin page i added artist name no issue. Then in the album section in the drop down it`s showing like album object instead of what i given the artist name. what is that for ?
Django doesn't know you want to use artist_name as a string representation of the Artist object. You need to add a __unicode__ (or __str__ on Python 3) method to your Artist model:
def __unicode__(self):
return self.artist_name
Even better if you want to be in sync with python 2 and 3:
At the top of your models:
from __future__ import unicode_literals
then before your class:
#python_2_unicode_compatible
class YourClass(models.Model):
And then:
def __str__(self):
return '%s' % self.title
I have one listing model :
class Listing(models.Model):
owner = models.ForeignKey(User, verbose_name=_('offerer'))
title = models.CharField(_('Title'), max_length=255)
slug = models.CharField(editable=False, max_length=255)
price = models.PositiveIntegerField(_("Price"), null=True, blank=True)
description = models.TextField(_('Description'))
time = models.DateTimeField(_('Created time'),
default = datetime.now,
editable = False
)
Then I have one ListingImage, which holds the pictures of the listing:
from photologue.models import ImageModel
class ListingImage(ImageModel):
pictures = models.ForeignKey(Listing, related_name="images")
forms.py
class ListingForm(forms.ModelForm):
class Meta:
model = Listing
exclude = ('owner',)
def __init__(self, *args, **kwargs):
super(ListingForm, self).__init__(*args, **kwargs)
Why in the upload page , there is no field to upload a picture??
ListingImage has a ForeignKey to Listing, so a ModelForm for Listing has nothing to do with ListingImage.
You shouldn't be expecting a ModelForm for the Listing model to show you anything but the Listing model. ListingImage is a reverse relationship to the Listing model.
If this was a ModelAdmin, you'd get the admin site to show you these reverse relationships by defining inlines:
http://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.InlineModelAdmin
Since it doesn't look like you're talking about the admin panel, you're looking at InlineModelFormsets: http://docs.djangoproject.com/en/dev/topics/forms/modelforms/#using-an-inline-formset-in-a-view
Also, you could show us your views so that we can see the whole picture.