Django admin: adding objects for foreignkey from other side - python

so I have these two models
class Recipe(models.Model):
short_description = HTMLField(max_length=400)
likes = models.ManyToManyField(User, blank=True, related_name='recipe_likes')
slug = models.SlugField(blank=True, unique=True)
published_date = models.DateTimeField(blank=True, default=datetime.now)
ratings = GenericRelation(Rating, related_query_name='recipes')
class Ingredient(models.Model):
name = models.CharField(max_length=20)
amount = models.FloatField()
recipe = models.ForeignKey(Recipe, on_delete=models.CASCADE, related_name='recipe_ingredients')
In the admin panel from the recipes section, if I choose a recipe I want to be able to add ingredients for that recipe, what do I need? I think I don't know the right searchterms to use, hope you understand what I mean.
Thanks for the help.
EDIT
This is the solution:
from django.contrib import admin
from .models import Recipe, Ingredient
class IngredientInline(admin.TabularInline):
model = Ingredient
extra = 3
#admin.register(Recipe)
class RecipeAdmin(admin.ModelAdmin):
list_display = ('title',)
search_fields = ('title', )
inlines = [IngredientInline,]

from django.contrib import admin
from .models import Recipe, Ingredient
class IngredientInline(admin.TabularInline):
model = Ingredient
extra = 3
#admin.register(Recipe)
class RecipeAdmin(admin.ModelAdmin):
list_display = ('title',)
search_fields = ('title', )
inlines = [IngredientInline,]

You'll want to read up on InlineModelAdmins:
https://docs.djangoproject.com/en/3.1/ref/contrib/admin/#inlinemodeladmin-objects
When you register your models with a model admin class, add an inlines list.
The documentation is good on this, so please expand your question if you have more detailed questions!

Related

how to add a new record to a Many To Many Field

I'm working on a small project using Django / Rest Framework, I have two models ( Contact & List )
I have Many To Many field, in Contact called list.
I would like to know how can I add a record to this relation ( Many To Many Field ).
from django.db import models
# Create your models here.
class List(models.Model):
name = models.CharField(blank=False, max_length=255)
comment = models.CharField(blank=False, max_length=255)
private = models.BooleanField(default=False)
allowed = models.BooleanField(default=False)
def __str__(self):
return self.name
This is my Contact Model
from django.db import models
from django.conf import settings
from list.models import List
# Create your models here.
class Contact(models.Model):
# field variables
language_choices = (
('french', 'french'),
('english', 'english'),
)
""" Relations Between Models """
list = models.ManyToManyField(List)
I looked for a solution for a long time.
Here is my method.
models.py
class Candidate(models.Model):
skills = models.ManyToManyField(Skill, through='SkillExperience')
class SkillExperience(models.Model):
"""Skills and experiences for a candidate"""
skill = models.ForeignKey(Skill, on_delete=models.CASCADE, related_name='skill_to_candidate')
candidate = models.ForeignKey(Candidate, on_delete=models.CASCADE, related_name='candidate_to_skill')
experience = models.ForeignKey(Experience, on_delete=models.CASCADE, related_name='experience_to_candidate', default=1)
serializer.py
class CandidateSkillExperienceSerializer(serializers.ModelSerializer):
experience = ExperienceSerializer(many=False, allow_null=True)
skill = SkillSerializerLite(many=False, allow_null=False)
class Meta:
model = SkillExperience
fields = ('skill', 'experience')
class CandidateSerializer(serializers.ModelSerializer):
candidate_to_skill = CandidateSkillExperienceSerializer(many=True, required=False, allow_null=True)

Get Django admin.ModelAdmin to display join of two tables

I have a Django app with the following models.py
from django.db import models
class Order(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
email = models.EmailField()
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
paid = models.BooleanField(default=False)
delivered = models.BooleanField(default=False)
class OrderItem(models.Model):
order = models.ForeignKey(Order,
related_name='items',
on_delete=models.CASCADE)
product = models.ForeignKey(Product,
related_name='order_items',
on_delete=models.CASCADE)
price = models.DecimalField(max_digits=10, decimal_places=2)
And in my admin.py, I have this
from django.contrib import admin
#admin.register(Order)
class OrderAdmin(admin.ModelAdmin):
list_display = ['id', 'first_name', 'last_name', 'email',
'paid', 'delivered']
list_filter = ['paid', 'delivered']
This only shows the Order table.
I would like to join the Order with the OrderItem table and display it in the Django admin. I am not sure this is relevant but for one Order, there could be many OrderItem(s).
As far as I know, you can't show OrderItems in OrderAdmin directly. But you can show Order in OrderItemAdmin, or use InLineModelAdmin to show OrderItems in Order Detail page. Like this:
class OrderItemInline(admin.TabularInline):
model = OrderItem
class OrderAdmin(admin.ModelAdmin):
inlines = [
OrderItemInline,
]
If you still want to display OrderItems (or parts of order item) in admin page, then you can add a method in list_display field, and use that method to fetch OrderItems. Like this:
class OrderAdmin(admin.ModelAdmin):
list_display = (..., 'get_order_items')
def get_order_items(self, obj):
return return ", ".join(obj.items.values_list("pk", flat=True))
get_order_items.short_description = 'Order Items'

Django-mptt admin categories

In my Django project I have a model:
class Category(MPTTModel):
name = models.CharField(default='',
max_length=50,
verbose_name='Название')
slug = models.SlugField(default='')
parent = TreeForeignKey('self',
related_name='children',
null=True,
blank=True,
verbose_name='Родительская категория'
)
order = models.PositiveSmallIntegerField(blank=False,
null=False,
default=0,
verbose_name='Порядок')
is_active = models.BooleanField(default=True,
db_index=True,
verbose_name='Отображать на сайте')
class Meta:
verbose_name = 'Категория'
verbose_name_plural = 'категории'
class MPTTMeta:
order_insertion_by = ['order']
If I add the main categories first (one, two, three), and then add subcategories (four in one, five in two, six in three), I would like to see it in the admin panel like this:
-one
--four
-two
--five
-three
--six
But I have this ordering:
-one
-two
-three
--four
--five
--six
What am I doing wrong?
You need to register Category model with MPTTModelAdmin
In your admin.py
from django.contrib import admin
from mptt.admin import MPTTModelAdmin
from .models import Category
admin.site.register(Category, MPTTModelAdmin)
Reference: https://django-mptt.github.io/django-mptt/admin.html
Thanx! It seems that SortableModelAdmin from suit.admin broke an order.
My admin.py was:
from suit.admin import SortableModelAdmin
from mptt.admin import MPTTModelAdmin
from .models import Category, Good
class CategoryAdmin(MPTTModelAdmin, SortableModelAdmin):
mptt_level_indent = 20
list_display = ('name', 'slug', 'is_active', 'order')
list_editable = ('is_active',)
prepopulated_fields = {"slug": ("name",)}
# Specify name of sortable property
sortable = 'order'
admin.site.register(Category, CategoryAdmin)

list_display doesn't work

There is a class named Employees in models.py
class Employees(models.Model):
employee_id = models.CharField(verbose_name = _("Employee ID"), max_length=20, primary_key=True)
employee_name = models.CharField(verbose_name = _("Employee Name"), max_length=20)
department = models.CharField(verbose_name = _("Department"), max_length=100)
post = models.CharField(verbose_name = _("Post"), max_length=100)
Then I wrote some code in admin.py
class EmployeesAdmin(admin.ModelAdmin):
list_display = ('employee_id', 'employee_name', 'department', 'post')
According to the tutorial, there should be four fields in the Employee branch. But in my situation, there is only one field named Employees, just like I didn't add EmployeesAdmin class in admin.py. What's wrong with it? Did I miss something?
admin.py:
from django.contrib import admin
from .models import Employees, Purchase, ProductsOut
# Register your models here.
admin.site.register(Employees)
admin.site.register(Purchase)
admin.site.register(ProductsOut)
Register your admin in admin.site like:-
admin.site.register(ModelName, AdminName)
Try the following after declaring your EmployeesAdmin class in admin.py:
admin.site.register(Employees, EmployeesAdmin)

Django limit next inlinefield to first inlinefield

I have this model in django
from django.db import models
class ProductType(models.Model):
name = models.CharField(max_length=250)
slug = models.SlugField(unique=True)
def __unicode__(self):
return self.name
class Product(models.Model):
name = models.CharField(max_length=250)
slug = models.SlugField(unique=True)
type = models.ForeignKey(ProductType, related_name='product_type')
related_products = models.ManyToManyField('self',blank=True,null=True)
description = models.TextField()
def __unicode__(self):
return self.name
What I would like to do is in the admin have the Products as tabular inline to a quote page that have multiple products. This thing is that the first selected model can be a parent to the others and therefore I would like the choices of the next elements to be sorted by the first.
this is the quote model
from django.db import models
from django.utils.translation import ugettext as _
import datetime
from products.models import Product
from customers.models import Customer
class Quote(models.Model):
quoteid = models.IntegerField(_('Quote ID'), max_length=8, unique=True, default=number)
slug = models.SlugField(unique=True,default=number)
add_date = models.DateTimeField(auto_now_add=True)
customer = models.ForeignKey(Customer, related_name='quote_customer',blank = True, null = True)
product = models.ManyToManyField(Product, related_name='quote_product')
def __unicode__(self):
return str(self.quoteid)
and the admin part
from django.contrib import admin
from quotes.models import Quote
class ProductInline(admin.TabularInline):
model = Quote.product.through
extra = 3
class QuoteAdmin(admin.ModelAdmin):
prepopulated_fields = {'slug': ('quoteid',)}
fieldsets = (
(('Quote'), {'fields': ('slug','quoteid','customer',)}),
)
list_display = ('quoteid','customer','add_date',)
inlines = [ ProductInline]
admin.site.register(Quote,QuoteAdmin)
I know this is quite tricky and I have tried many ways but I have not found a solution that works. I have tried with formfield_for_manytomany but I can't fully grasp how to return the first tabularinline object as the input for the queryset.
If someone have a link that explains a method to do this I would be grateful.

Categories

Resources