Title field in admin - django

I have a model:
class Review(models.Model):
name = models.CharField(max_length = 50)
link = models.CharField(max_length = 100)
book_id = models.IntegerField()
review_id = models.IntegerField()
content = models.TextField()
rating = models.IntegerField()
author = models.CharField(max_length = 50)
If I open admin http://127.0.0.1:8000/admin/my_app/review/ I'll see the list of records. For each record Django Admin display only one field ('Name' in my case). How Django Admin choise the field to display in the list of records.
Firstly I thinked that it is a first field in my model. I have moved Name-field down in the field list and recreate the database, but there was nothing to change.

Django calls the __unicode__ method on the model. For configuring the displayed fields in the change list see the detailed documentation!

Related

Django ORM Query Optimization Issue

I am making a blog website and I am facing some issues with the Query performance.
I have 3 models
User Model -> Users (To store user email, Password etc)
Post Model -> Actual Posts
people Model -> (To store users extra information)
Post Model ->
class Post(models.Model):
user = models.ForeignKey(User, on_delete=models.PROTECT)
category = models.ForeignKey(Category, on_delete=models.PROTECT)
title = models.CharField(max_length=255,null=True)
description = models.CharField(max_length=1000,null=True)
Likes = models.ManyToManyField(to=User, related_name='Post_likes')
favourites = models.ManyToManyField(to=User,blank=True,related_name="favourite")
People Model ->
class People(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
photo = models.ImageField(upload_to='profile_pics', blank=True,null=True)
Phone_number = models.CharField(max_length=255,null=True,blank=True)
Birth_Date = models.DateField(null=True,blank=True)
Created_date = models.DateTimeField(auto_now_add=True)
Updated_date = models.DateTimeField(auto_now=True)
Now as both of these models are connected to User model. I want to query the Post model and get the user photo in the template. Now when I use post.user.people.photo then for every post it generates a seperate query to DB resulting in slowness. I would like to use Join here to combines multiple tables and fetch all the records at once.
I am currently using following Query ->
posts = Post.objects.select_related().prefetch_related('images_set').annotate(comments_Count = Count('comments_post',distinct=True)).annotate(Count('Likes',distinct=True)).all().order_by('-id')
You can perform a .select_related(…) [Django-doc] on the user and the people with user__people, so:
posts = Post.objects.select_related(
'user__people', 'category'
).prefetch_related('images_set').annotate(
comments_Count = Count('comments_post',distinct=True),
Count('Likes',distinct=True)
).order_by('-id')
Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.

how to update a model data from the admin panel in django

so i was creating a ecommerce site , what i wanted to do was when i added a product through admin panel , it would increase the count as well from model.
eg:
in the below model ,when i add an a item from admin panel i want it to find the object and add the objects stock with the new stock number i provided , if both these added items have the same names.
class Item(models.Model):
name = models.CharField(max_length=100)
price = models.FloatField()
product = models.ForeignKey(Product, on_delete=models.CASCADE)
desc = models.TextField()
img = models.ImageField(upload_to='uploads/items', blank=True)
stock = models.IntegerField()
def __str__(self):
return self.name
Simply use Update View available in Django.
Here is an official Documentation. Link

Django query categories, exclude those without posts

I have these two models, post and categories.
class Category(models.Model):
""" Categories """
name = models.CharField(max_length = 80, help_text="Enter a descriptive and unique category name.")
slug = models.SlugField(max_length = 250, help_text="The slug is used to link category pages.")
class Post(models.Model):
""" Blog posts """
author = models.ForeignKey(User, related_name='blog_posts', on_delete = models.CASCADE)
category = models.ForeignKey(Category, related_name = 'blog_posts', on_delete = models.CASCADE)
title = models.CharField(max_length=250)
body = models.TextField(help_text = "Type your blog post using plain text or mark-down format.")
I am trying to query all the categories that have posts, excluding categories which don't have yet posts. The SQL equivalent of:
SELECT * FROM category WHERE id IN (SELECT DISTINCT(category_id) FROM post)
Many thanks!
You can use annotation to count the posts and then filter based on the result:
from django.db.models import Count
Category.objects.annotate(posts_count=Count("blog_posts")).filter(post_count__gt=0)

How do I filter Choice FK in Forms?

I want filter a choice in a form according user_logged. Here is my models.
#models.py
class Store(models.Model):
name = models.CharField(max_length=64, unique=True)
description = models.TextField(null=True, blank=True)
class StoreManager(models.Model):
store = models.ForeignKey(Store, related_name='store', on_delete=models.CASCADE)
user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
class StoreLogo(models.Model):
store = models.ForeignKey(Store, related_name='store', on_delete=models.CASCADE, verbose_name='Store')
image = photo = models.FileField()
First I created a Store, after that I Associate a StoreManager to a Store, and then I want in a forms add a ImageLogo, so in that forms, in field Store, I want list only a Store what user has associated.
Store = (SuperMarket Store), (ClothesStore)
StoreManager = John(SuperMarket Store), Julian(ClothesStore)
StoreLogo = John (can only view SuperMarket Sotre)
StoreLogo = Julian(can only view ClothesStore)
I'm using CBV(generic.CreateView).
There is my views.
#views.py
class AddPhotoOnEstablishment(LoginRequiredMixin, generic.CreateView):
model = StoreLogo
fields = ['store', 'image']
success_url = reverse_lazy('register:establishment_list')
context_object_name = 'object_name'
I want, if John has associated to Store and logged in the system, when he add a Image logo, the field Store only appear the Store he has associated.
maybe this link will help. it explained methods and attributes of CreateView class. in the render_to_response method you can get the current user using this code:
self.request.user
and check if it's associated with the store logo you're sending as response.

Django: How can I add/delete fields in sqlite3 database?

I've started learning Django from a YouTube course.
In the models.py file, there are two classes.
class Album(models.Model):
artist = models.CharField(max_length = 250)
album_title = models.CharField(max_length = 250)
album_logo = models.CharField(max_length = 1000)
def __str__(self):
return self.album_title + ' - ' + self.artist
class Song(models.Model):
album = models.ForeignKey(Album, on_delete=models.CASCADE)
file_type = models.CharField(max_length=10)
song_title = models.CharField(max_length=250)
genre = models.CharField(max_length=250)
def __str__(self):
return self.song_title
I added the genre in the Song after the migration. That's why I'm having problem while adding data.
In the interactive shell, if I try to save() , it shows there's no 'genre' field. If I try to migrate again, it shows something like this:
You are trying to add a non-nullable field 'genre' to song without a
default; we can't do that (the database needs something to populate
existing rows). Please select a fix:
1) Provide a one-off default now
(will be set on all existing rows with a null value for this column)
2) Quit, and let me add a default in models.py Select an option:
What's the proper way of adding or deleting fields?
add default="" to genere field
class Song(models.Model):
album = models.ForeignKey(Album, on_delete=models.CASCADE)
file_type = models.CharField(max_length=10)
song_title = models.CharField(max_length=250)
genre = models.CharField(max_length=250, default="")
def __str__(self):
return self.song_title
As the error message shows, you add a field genre to Song model without adding default="" nor null=True parameters to it. When you migrate it, django don't know how to deal with the old data that has been inserted into the database without genere field. So you should set them to null with null=True or other default value with default="".
You can also just keep your code. But when you use the migrate command, you should tell django that you will give a default value like the django recommanded:
1) Provide a one-off default now (will be set on all existing rows with a null value for this column)
press 1 and enter key. input "" and then django will set all the old data genre="".