Django admin - Inline with choices from database - python

I need some basic help with the django admin site. What I basically want to do is to be able to populate an inline with choices from the database. For example consider the following models:
class Item(models.Model):
description = models.CharField(max_length=100)
class Category(models.Model):
name = models.CharField(max_length=100)
item = models.ForeignKey(Item, on_delete=models.CASCADE, null=True, blank=True)
And in admin.py I have the following setup:
class CategoryAdminForm(forms.ModelForm):
name = forms.ChoiceField(choices = category_service.get_all_categories())
class CategoryInline(admin.TabularInline):
model = Category
form = CategoryAdminForm
class ItemAdmin(admin.ModelAdmin):
inlines = [CategoryInline]
admin.site.register(Item, ItemAdmin)
admin.site.register(Category)
What I want to be able to do is to insert categories into db, and when I want to insert an item, the categories inline to be populated with categories from the db.
With the current setup it is not working. It says that category is not an iterable object. What am I missing here?

You should replace your ChoiceField with a ModelChoiceField. They allow you to specify a queryset to populate the choices.
category = forms.ModelChoiceField(queryset=Category.objects.all(), empty_label="(Nothing)")

Related

Django: Filter records based on one to many relationship

I have following models,
class User(models.Model):
name = models.CharField(max_length=255)
...
class InsuranceProfile(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
...
class ProductExpertiseMaster(models.Model):
class Meta:
db_table = 'product_expertise_master'
name = models.CharField(max_length=255)
main_category = models.CharField(max_length=255)
class UserProductExpertise(models.Model):
user = models.ForeignKey(User, on_delete=models.DO_NOTHING)
product_expertise = models.ForeignKey(ProductExpertiseMaster, on_delete=models.DO_NOTHING)
So what I am trying to do is I want to filter records based on various fields some of the belong to User model & some of them belong to the InsuranceProfile model.I am filter the records based on User & InsuranceProfile model which is working fine. Now i want to add one more filter which will be based on the UserProductExpertise model.I want to get all the InsuranceProfiles with User details who have some matching condition with product expertise entries in UserProductExpertise model. Any help would appreciated.
You can try like this using __isnull:
InsuranceProfile.objects.filter(user__userproductexpertise__isnull=False)
It will return all the users who has an entry in in UserProductExpertise model. For querying, you need to use all lowercase of the model name, (ie userproductexpertise) and add __isnull at the end of it.
I think you should make some changes in your models before proceeding further.
UserProductExpertise model is the bridge table between ProductExpertiseMaster and User, which provides a many-to-many relationship. If you won't add additional fields to UserProductExpertise model, you can drop it and define user relation in ProductExpertiseMaster model.
If you prefer using seperate model for this relationship, on_delete=models.DO_NOTHING is prone to errors, you can change it to models.CASCADE
Here is an example with many-to-many relation:
class User(models.Model):
name = models.CharField(max_length=255)
class InsuranceProfile(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
content = models.CharField(("Content"), max_length=500)
class ProductExpertiseMaster(models.Model):
class Meta:
db_table = 'product_expertise_master'
name = models.CharField(max_length=255)
main_category = models.CharField(max_length=255)
user = models.ManyToManyField(User, verbose_name=("Users"), related_name="expertises")
For filtering your query:
InsuranceProfile.objects.filter(user__expertises__isnull=False)

How to create an Inline through a chain of foreign keys in Django admin?

Supposing I have these Django models:
class Genre(models.Model):
name = models.CharField(max_length=255)
class Author(models.Model):
name = models.CharField(max_length=255)
genre = models.ForeignKey('Genre')
class Book(models.Model):
name = models.CharField(max_length=255)
author = models.ForeignKey('Author')
I want to define inlines in Django Admin for a Genre instance showing all related books. How can I do it?
I tried this way:
class BookInline(admin.TabularInline):
model = Book
extra = 0
class GenreAdmin(admin.ModelAdmin):
inlines = [BookInline]
admin.site.register(Genre, GenreAdmin)
that brought me the error:
ValueError: 'Book' has no ForeignKey to 'Genre'
How can I define the inline correctly?
You should put Genre on the Book, and then create a method on the Authors that will list the book's genres on it, so basically Authors genre's will be populated from Books.

How to display all available choices of a manytomany field in django admin using filter_horizontal

I have two models that have many to many relationship. One model consists of all possible choices and the other model can have some or all of those choices.
These are the two models:
class LanguageDomains(models.Model):
DOMAIN_CHOICES=(
('Choice1', _(u'Choice1')),
('Choice2', _(u'Choice2')),
('Choice3', _(u'Choice3')),
('Choice4', _(u'Choice4')),
)
# There is many more choices in the actual code
domains = models.CharField(max_length=255, choices=DOMAIN_CHOICES, default=None)
def __unicode__(self):
return self.domains
class Revitalization(models.Model):
code = models.ForeignKey(Codes, related_name ='revitalization')
program_name = models.CharField(max_length=255, null=True, blank=True)
year_founded = models.CharField(max_length=4, null=True, blank=True)
some_domains = models.ManyToManyField(LanguageDomains, related_name='revitalization')
def __unicode__(self):
return self.code.primary_name
My admin.py:
class RevitalizationAdmin(admin.ModelAdmin):
list_display = ('code','id')
filter_horizontal = ('language_domains',)
This is what the admin console looks like:
The question is, is there a way to populate the "Available language domains" list with all the DOMAIN_CHOICES from LanguageDomains model?
You could write a data migration that will populate the LanguageDomains model table with all the available choices.
Depending on your use-case, if the sole purpose of LanguageDomains is to present multiple choices and it's not going to be edited in runtime look into using django-multiselectfield.

Django one-to-many, add fields dynamically in Admin

I have the following code:
class Item(models.Model):
name = models.CharField(max_length=100)
keywords = models.CharField(max_length=255)
type = models.ForeignKey(Type)
class Meta:
abstract = True
class Variant(models.Model):
test_field = models.CharField(max_length=255)
class Product(Item):
price = models.DecimalField(decimal_places=2, max_digits=8,null=True, blank=True)
brand = models.ForeignKey(Brand)
variant = models.ForeignKey(Variant)
def get_fields(self):
return [(field.name, field.value_to_string(self)) for field in Product._meta.fields]
def __unicode__(self):
return self.name
Im using Grappelli.
I want my Product to have multiple Variations. Should I use a manytomanyfield?
I want to be able to add Variants to my Product directly in the Admin. Now I get an empty dropwdown with no variants(because they doesnt exists).
I thought Django did this automatically when u specified a Foreign Key?
How can I get the Variant fields to display directly on my Product page in edit?
I've read someting about inline fields in Admin?
Well, it's the other way around :)
1/ Place the foreign key field in your Variant, not in your Product (what you describe is actually a OneToMany relationship).
2/ Link the Variant to your Product in the relative ProductAdmin in admin.py as an inline (i.e VariantInline).
See the docs for further informations : https://docs.djangoproject.com/en/1.6/ref/contrib/admin/#inlinemodeladmin-objects
Hope this helps !
Regards,

Django forms with Foreign keys

I have scenario in which a user can have multiple books. I can create two different models for user and books and relate them using foreign keys (or one-to-many will be right way ?).
I have created a django forms for User model but when i do like this {{form.as_p}} in templates only user model fields is shown not books field.
I want that with user fields my books model filed also displayed (like book names field more then once because he can have multiple books) , Please let me know if it is possible using django forms/models or I have to user simple html forms with jquery and then save data in models.
Thanks
EDIT:
my models :
class Product(models.Model):
categories = models.CharField(max_length=5, choices = settings.CATEGORIES)
name = models.CharField(max_length=100)
description = models.TextField()
currency = models.CharField(max_length=5, choices = settings.CURRENCY)
status = models.BooleanField(default=True)
def __unicode__(self):
return self.name
class Prices(models.Model):
products = models.ForeignKey(Product)
prices = models.IntegerField()
def __unicode__(self):
return self.id
if you are creating a form for Prices, try putting this in your model form:
products = forms.ModelMultipleChoiceField(queryset=Product.objects.all())
I think you should add required fields in meta class such as
class ThreadForm(ModelForm):
class Meta:
model = Thread
fields = ('Books', 'User')
Please understand the work flow to use foreign keys in model form here.

Categories