How can I dispay the data in django admin panel - python

I am creating an eCommerce website but I want to know how can I display a product_name or customer_name in the admin panel.
The concept is that if a customer places an order that it will go to the admin panel. So the other details are displaying properly except product_name or customet_name.
As shown in the below image:
models.py
class Order(models.Model):
product = models.ForeignKey(Product, on_delete=models.CASCADE)
customer = models.ForeignKey(Customer, on_delete=models.CASCADE)
quantity = models.IntegerField(default=1)
address = models.CharField(max_length=50, default='', blank=True)
phone = models.CharField(max_length=50, default='', blank=True)
price = models.IntegerField()
date = models.DateField(default=datetime.datetime.today)
status = models.BooleanField(default=False)
admin.py
class AdminOrders(admin.ModelAdmin):
list_display = ['product', 'customer', 'quantity', 'address', 'phone', 'price', 'date', 'status']

You need to define the __str__ method in the models Product and Customer
Example:
def __str__(self):
return self.name

If you call a function it have to return string if you want to display as word.
I know 2 ways to do this
First its repr Method
def __repr__(self):
return self.(Model You wanna Display)
or str Witch is akcually same
def __str__(self):
return self.(Model You wanna Display)

Have tried double underscore in order to access the foreign item field (product__name) and (customer__name).
class Product(models.Model):
name= models.CharField(max_length=50, default='', blank=True)
....
class Customer(models.Model):
name= models.CharField(max_length=50, default='', blank=True)
....
class AdminOrders(admin.ModelAdmin):
list_display = ['product__name', 'customer__name', 'quantity', 'address', 'phone', 'price', 'date', 'status']

Related

nested serialization dont now create a forignkey it requires a new Object instead of 'id'

here is my model, serializer and output but when i want to create a new page it ask me to add a whole new user as its just a foreign-key it need to be a number like 1 (user id) and same in the case of categories how can i solve it.... help me please
serializers.py
class TeamMembersSerializer(serializers.ModelSerializer):
class Meta:
model = TeamMembers
fields = [
'user',
'page',
]
depth = 1
class SocialAccountsSerializer(serializers.ModelSerializer):
social = SocialCatSerializer()
class Meta:
model = SocialAccounts
fields = [
'page',
'social',
'link'
]
depth = 1
class PageImageSerializer(serializers.ModelSerializer):
class Meta:
model = PageImages
fields = [
'page',
'image',
]
depth = 1
class PageSerializer(serializers.ModelSerializer):
owner = UserSerializer()
catagory = BusinessCatSerializers()
business_type = BusinessTypeSerializer()
TeamMembers = TeamMembersSerializer(read_only=True)
social_accounts = SocialAccountsSerializer(read_only=True)
images = PageImageSerializer(read_only=True)
class Meta:
model =Page
fields = [
'id',
'owner',
'catagory',
'name',
'username',
'images',
'start_date',
'business_type',
'contect_number',
'email_address',
'website',
'TeamMembers',
'social_accounts',
'about',
'impression',
'Awards',
'Product',
'privacy_policy',
'is_active',
]
Models.py
class Page(models.Model):
owner = models.ForeignKey(User, on_delete=models.CASCADE)
catagory = models.ForeignKey(BusinessCatagories, on_delete=models.CASCADE, null=True, blank=True, default=None)
name = models.CharField(max_length=254, unique=True ,default=None, blank=True)
username = models.CharField(max_length=254, unique=True, blank=True)
start_date = models.DateTimeField(auto_now_add=True)
business_type = models.ForeignKey(BusinessType, on_delete=models.CASCADE, null=True, blank=True, default=None)
contect_number = models.CharField(max_length=254, default=None, blank=True)
email_address = models.EmailField(default=None, blank=True)
website = models.URLField(default=None, blank=True)
about = models.TextField(default=None, blank=True)
impression = models.TextField(default=None, blank=True)
Awards = models.CharField(max_length=254, default=None, blank=True)
Product = models.CharField(max_length=254, default=None, blank=True)
privacy_policy = models.URLField(default=None, blank=True)
is_active = models.BooleanField(default=True)
def __str__(self):
return self.name
class TeamMembers(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, default=None, blank=True)
page = models.ForeignKey(Page, on_delete=models.CASCADE, default=None, blank=True)
def __str__(self):
return self.user.name
class SocialAccounts(models.Model):
page = models.ForeignKey(Page, on_delete=models.CASCADE, default=None, blank=True)
social = models.ForeignKey(SocialCats, on_delete=models.CASCADE, default=None, blank=True)
link = models.URLField(default=None, blank=True)
def __str__(self):
return self.link
class PageImages(models.Model):
page = models.ForeignKey(Page, on_delete=models.CASCADE, default=None, blank=True)
image = models.ImageField(default=None, blank=True, upload_to=settings.MEDIA_ROOT)
def __str__(self):
return self.page.name
output is this but i need images field TeamMember field in it but its not appearing plus it want me to add a new user instead of asking for Foreignkey "id"
What you want is to use Primary key related field. It helps you to represent the target of the relationship using its primary key.
It should look somewhat like this.
Note: Mind the typo for any name
class PageSerializer(serializers.ModelSerializer):
owner = serializers.PrimaryKeyRelatedField(queryset = User.objects.all())
catagory = serializers.PrimaryKeyRelatedField(queryset = BuisnessCat.objects.all())
business_type = BusinessTypeSerializer()
TeamMembers = TeamMembersSerializer(read_only=True)
social_accounts = SocialAccountsSerializer(read_only=True)
images = PageImageSerializer(read_only=True)
You can read more about PrimaryKeyRelatedField here.
Now whenever creating any Page, all you need to supply are primary key for owner and category.
You are looking for Writable Nested Serializer.
In short you have to override create() method of PageSerializer
class PageSerializer(serializers.ModelSerializer):
....
....
your code
def create(self, validated_data):
# pop data of every related fields like "owner", "cateagory" etc from validated_data
owner = validated_data.pop("owner")
owner = User.objects.create(**owner)
category = validated_data.pop("category")
# create or retrieve category instance ,as above
...
...
...
# finally
return Page.objects.create(**validated_data,owner=owner,category=category, and other related instances)

Django Admin: edit view shows no fields at all

I have defined a couple of models in a new Django 1.8 app.
When I visit the Django Admin, the list view (the table where you see one row per each objects instance) works fine.
My surprise is that when I click on any NSGateway item and enter the edit or create page, there are no fields; just the Save buttons.
How can this be possible? All the NSGateway fields are shown as columns in the list view. But the edit view shows no fields!
These are the models:
from django.db import models
class Enterprise(models.Model):
enterprise_id = models.CharField(max_length=40, primary_key=True)
description = models.CharField(max_length=500, null=True)
name = models.CharField(max_length=500)
creationDate = models.DateTimeField()
lastUpdatedDate = models.DateTimeField()
def __unicode__(self):
return self.description
class NSGateway(models.Model):
nsgateway_id = models.CharField(max_length=40, primary_key=True)
creationDate = models.DateTimeField()
description = models.CharField(max_length=500, null=True)
lastUpdatedDate = models.DateTimeField()
personality = models.CharField(max_length=50)
name = models.CharField(max_length=500)
# Each NSG belongs to 1 and only 1 Enterprise.
# Thus, when we delete de Enterprise, we delete its NSG
enterprise = models.ForeignKey(Enterprise, on_delete=models.CASCADE)
def __unicode__(self):
return self.description
This is how the corresponding admin.py:
from django.contrib import admin
from flexwan_import.models import Enterprise, NSGateway
class EnterpriseAdmin(admin.ModelAdmin):
list_display = ('enterprise_id', 'name', 'description', 'creationDate',
'lastUpdatedDate')
search_fields = ['enterprise_id', 'description']
class NSGatewayAdmin(admin.ModelAdmin):
list_display = ('nsgateway_id', 'name', 'description', 'creationDate',
'lastUpdatedDate')
search_fields = ['nsgateway_id', 'description']
admin.site.register(Enterprise, EnterpriseAdmin)
admin.site.register(NSGateway, NSGatewayAdmin)

Django - Admin ListFilter on QuerySet witn .extra()

More than one day trying to figure out on how to use the Django Admin list_filter on a QuerySet using .extra()
In the AdAdmin I need to add one new column 'ad_hist_status_id' from the model AdHist so I can use this portion of the code on SomeListFilter:
def queryset(self, request, queryset):
return queryset.filter(ad_hist_status_id=self.value())
It looks like impossible. Doing this with sql is easy:
select a.*, ah.ad_hist_status_id from ad_ad a
join ad_adhist ah on ah.ad_id = a.id
where
ah.datetime_end is null
order by a.id DESC
Until now I cannot make to work this SomeListFilter in the Django Admin, the error is:
FieldError at /admin/ad/ad/
Cannot resolve keyword 'ad_hist_status_id' into field.
Choices are: addetailscategories, address, adhist, adphotos,
adprice, adscheduleinfo, age, comment, county, county_id,
date_inserted, date_updated, description, district, district_id,
email, id, lat, lng, name, parish, parish_id, schedule_type,
schedule_type_id, telephone, title, user_inserted, user_inserted_id,
user_updated, user_updated_id
My question is, how do I effectively add a new column to a QuerySet and then how can I query this new QuerySet with the new column?
Some portions of my code bellow
The Models:
class Ad(models.Model):
title = models.CharField(max_length=250)
name = models.CharField(max_length=100)
description = models.TextField()
age = models.IntegerField(blank=True, null=True)
telephone = models.CharField(max_length=25)
email = models.EmailField()
district = models.ForeignKey(District)
county = ChainedForeignKey(County, chained_field="district", chained_model_field="district", sort=True) # smart_selects app
parish = ChainedForeignKey(Parish, chained_field="county", chained_model_field="county", sort=True) # smart_selects app
address = models.CharField(max_length=250, null=True, blank=True)
lat = models.DecimalField(max_digits=9, decimal_places=6, null=True, blank=True)
lng = models.DecimalField(max_digits=9, decimal_places=6, null=True, blank=True)
schedule_type = models.ForeignKey(AdScheduleType)
comment = models.TextField(null=True, blank=True)
user_inserted = models.ForeignKey(User, null=True, blank=True, related_name='user_inserted_ad')
date_inserted = models.DateTimeField(auto_now_add=True)
user_updated = models.ForeignKey(User, null=True, blank=True, related_name='user_updated_ad')
date_updated = models.DateTimeField(null=True, blank=True)
def __str__(self):
return self.name
class AdHist(models.Model):
ad = models.ForeignKey(Ad)
datetime_begin = models.DateTimeField()
datetime_end = models.DateTimeField(null=True, blank=True)
ad_hist_status = models.ForeignKey(AdHistStatus)
ad_hist_change_reason = models.ForeignKey(AdHistChangeReason)
comment = models.TextField(null=True, blank=True)
user_inserted = models.ForeignKey(User, null=True, blank=True, related_name='user_inserted_ad_hist')
date_inserted = models.DateTimeField(auto_now_add=True)
user_updated = models.ForeignKey(User, null=True, blank=True, related_name='user_updated_ad_hist')
date_updated = models.DateTimeField(null=True, blank=True)
def __str__(self):
return self.ad.name
The Admin:
class SomeListFilter(admin.SimpleListFilter):
title = _('Approval State')
parameter_name = 'ad_hist_status_id'
def lookups(self, request, model_admin):
return (
('1', _('Approved')),
('4', _('Not Approved')),
)
def queryset(self, request, queryset):
return queryset.filter(ad_hist_status_id=self.value())
class AdAdmin(admin.ModelAdmin):
list_display = ('id', 'name', 'title', 'age', 'telephone',
'email', 'district', 'county', 'parish',
'ad_status', 'ad_hist_change_reason', 'comment',
'user_inserted', 'date_inserted', 'user_updated',
'date_updated', 'ad_hist_status_id')
readonly_fields = ('ad_status', 'id', 'ad_hist_change_reason',
'ad_hist_status_id')
list_filter = (SomeListFilter,)
def get_queryset(self, request):
qs = super(AdAdmin,self).get_queryset(request).extra(select={'ad_hist_status_id': 'select ad_hist_status_id from ad_adhist where ad_adhist.ad_id = ad_ad.id and ad_adhist.datetime_end is null'},)
return qs
def ad_hist_status_id(self, inst):
return inst.ad_hist_status_id
Can someone give me a clue?
Best Regards
If I understand your question right, you are looking for this:
from django.db.models import F
def queryset(self, request, queryset):
return queryset.filter(ad_hist_status__id=F('id'))
The F expression is used to reference a field from the same model, and to refer a field from a related model, you need to use an underscore (__).
Take a closer look to Django field lookups. Look at what the docs say:
Basic lookups keyword arguments take the form field__lookuptype=value. (That’s a double-underscore).
You want to take the AdHist related object from Ad, which has a related AdHistStatus, and get its id.
So you should access this id field like:
def ad_hist_status_id(self, instance):
return instance.adhist.ad_hist_status.id
Or you can list it directly with the double-underscore syntax:
class AdAdmin(admin.ModelAdmin):
list_display = (..., 'adhist__ad_hist_status__id')

Django Rest creating Nested-Objects (ManyToMany)

I looked for an answer to this question specifically for Django Rest, but I haven't found one anywhere, although I think a lot of people have this issue. I'm trying to create an object with multiple nested relationships but something is keeping this from happening. Here are my models for reference:
class UserProfile(models.Model):
user = models.OneToOneField(User, unique=True, null=True)
tmp_password = models.CharField(max_length=32)
photo = models.ImageField(upload_to='media/', blank=True, null=True)
likes = models.IntegerField(blank=True, null=True)
dislikes = models.IntegerField(blank=True, null=True)
def __unicode__(self):
return unicode(self.user.username)
class Item(models.Model):
"""Item Object Class"""
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=125, blank=True)
price = models.FloatField(default=0, blank=True)
rating = models.IntegerField(default=0, blank=True)
description = models.TextField(max_length=300, blank=True)
photo = models.ImageField(upload_to="media/", blank=True)
barcode = models.CharField(max_length=20, blank=True)
photo_url = models.URLField(max_length=200, blank=True)
item_url = models.URLField(max_length=200, blank=True)
def __unicode__(self):
return unicode(self.name)
class Favorite(models.Model):
user = models.OneToOneField(User, null=True)
items = models.ManyToManyField(Item)
def __unicode__(self):
return unicode(self.user.username)
def admin_names(self):
return '\n'.join([a.name for a in self.items.all()])
And here are my serializers:
class ItemSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Item
fields = ('id', 'name', 'price', 'description', 'rating', 'photo', 'barcode', 'photo_url','item_url' )
class FavoriteSerializer(serializers.ModelSerializer):
class Meta:
model = Favorite
exclude = ('id', 'user')
class UserProfileSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = UserProfile
fields = ('likes', 'dislikes', 'photo', 'tmp_password')
class UserSerializer(serializers.HyperlinkedModelSerializer):
userprofile = UserProfileSerializer()
favorite = FavoriteSerializer()
class Meta:
model = User
fields = (
'id', 'username', 'url',
'email', 'is_staff', 'password',
'userprofile', 'favorite'
)
def create(self, validated_data):
profile_data = validated_data.pop('userprofile')
favorites_data = validated_data.pop('favorite')
user = User.objects.create_user(**validated_data)
user_profile = UserProfile.objects.create(user=user, **profile_data)
favorite = Favorite(user=user)
favorite.save()
print favorite.items
for item in favorites_data:
favorite.items.add(item)
print favorite.items
return user
What I am having trouble with is the create() method on UserSerializer. What's happening is I can't .add() the data from favorites_data to the favorite object. I get an error saying invalid literal for int() with base 10: 'items'. I guess this makes sense, but if I try this instead of using the for loop:
favorite.items.add(**favorites_data)
I just get an error saying add() got an unexpected keyword argument 'items'. Finally, If I try this:
favorite.items.add(favorites_data)
I just get this error: unhashable type: 'OrderedDict'
What am I doing wrong in this approach? Obviously, favorites_data exist, but I'm not inserting it properly. Thanks for any help!
I think favorite.items.add expects you to pass in a single instance of an Item, so you should replace this:
for item in favorites_data:
favorite.items.add(item)
With this:
for key in favorites_data:
for item in favorites_data[key]:
favorite.items.add(item)

DRF Exception value: Cannot assign - it must be a instance

I know there are a bunch of questions addressing this issue, but I haven't solved it out yet. I'm using DRF for the first time and I'm working with nested serializers. My Restaurant serializer points to a Category serializer via a slug related field as it shows below
class CategorySerializer(serializers.ModelSerializer):
class Meta:
model = Category
fields = (
'name',
'description'
)
class RestaurantSerializer(serializers.HyperlinkedModelSerializer):
category = serializers.SlugRelatedField(
many=True,
read_only=False,
queryset=Category.objects.all(),
slug_field='name'
)
class Meta:
model = Restaurant
fields = (
'id',
'name',
'description',
'website',
'twitter',
'facebook',
'instagram',
'category'
)
I send all the necessary data to my endpoint to create a new Restaurant via jquery but I keep getting "Cannot assign "[< Category: Italian food >]": "Restaurant.category" must be a "Category" instance."
I understand I need to assign a Category object to Restaurant's category, although I don't know how to access my queryset to extract the object that matters.
Any advices on this?
Edit: This is the data I'm sending from jquery to my endpoint
{"name":"Restaurant","email":"restaurant#gmail.com","password":"1234","category":["Italian food"],"description":"Description test"}
Edit # 2 See the model definitions below
class Restaurant(models.Model):
name = models.CharField(max_length=80, null=False)
description = models.TextField(max_length=300, null=False)
email = models.EmailField(max_length=80, null=True)
password = models.CharField(max_length=60, null=False)
website = models.URLField(max_length=80, null=True)
twitter = models.CharField(max_length=60, null=True, blank=True)
facebook = models.CharField(max_length=60, null=True, blank=True)
instagram = models.CharField(max_length=60, null=True, blank=True)
category = models.ForeignKey('Category')
def __unicode__(self):
return self.name
class Category(models.Model):
name = models.CharField(max_length=80, null=False)
description = models.TextField(max_length=100, null=False)
def __unicode__(self):
return self.name
You have a ForeignKey from Restaurant to Category. That means there is only one Category for each Restaurant. But you are sending a list of category slugs, and you have many=True in the definition of the SlugRelatedField.
Your data should just be {..."category": "Italian food"...}, and you should remove the many=True.

Categories

Resources