Django inline has no ForeignKey but has one? - python

I want to try to add a ListField increasible on django admin. I discover I can do that with inlines, so I goes to the doc to find this code :
models.py
from django.db import models
class Author(models.Model):
name = models.CharField(max_length=100)
class Book(models.Model):
author = models.ForeignKey(Author, on_delete=models.CASCADE)
title = models.CharField(max_length=100)
admin.py
class BookInline(admin.TabularInline):
model = Book
class AuthorAdmin(admin.ModelAdmin):
inlines = [
BookInline,
]
I simply copy this code to see how it render on Django admin page.
But the following error appear :
<class 'users.admin.BookInline'>: (admin.E202) 'users.Book' has no ForeignKey to 'users.Book'.
I don't understand why because Book as a ForeignKey. Am I missing something ?
Thx

Related

How do I delete a field from my Django ModelForm?

I'm trying to hide and delete two fields from showing in a form I created in the Django administration page using ModelForm.
I looked at answers that said I should use the "exclude" meta field, but I don't know why it's not working in my case.
Here is my code:
models.py:
class Activity(models.Model):
type = models.CharField(max_length=50, default="")
title = models.CharField(max_length=200, default="")
description = models.CharField(max_length=500)
owner = models.ForeignKey(User, related_name="owner")
college = models.CharField(max_length=200)
location = models.CharField(max_length=200)
room = models.CharField(max_length=200)
startDate = models.DateTimeField(null=True, blank=True)
endDate = models.DateTimeField(null=True, blank=True)
attendee = models.ManyToManyField(Attendee, related_name="attendees",null=True, blank=True)
volunteer = models.ManyToManyField(Volunteer, related_name="volunteers",null=True, blank=True)
I'm trying to exclude the "attendee & volunteer" fields from displaying in the Django administration form.
In admin.py I have:
from django.contrib import admin
from django import forms
from KSUvity.models import Activity
class ActivityForm(forms.ModelForm):
class Meta:
model = Activity
exclude = ['attendee', 'volunteer',]
class ActivityAdmin(admin.ModelAdmin):
exclude = ['attendee', 'volunteer',]
form = ActivityForm
admin.site.register(Activity, ActivityAdmin)
You have to create an admin.py file in your app and register your models
Follow the instuctions
See the example below
from django import forms
from django.contrib import admin
from myapp.models import Person
class PersonForm(forms.ModelForm):
class Meta:
model = Person
exclude = ['name']
class PersonAdmin(admin.ModelAdmin):
exclude = ['age']
form = PersonForm
admin.site.register(Person, PersonAdmin)
You can use either fields or exclude in one class.
In your app admin field add this code.
app_name/admin.py
from django.contrib import admin
class ActivityAdmin(admin.ModelAdmin):
exclude = ('attendee', 'volunteer',)
You have to use ModelAdmin option to exclude fields from form in Django administration, either ModelAdmin.exclude or ModelAdmin.fields. Below is an example:
class ActivityAdmin(admin.ModelAdmin):
exclude = ('attendee', 'volunteer', )
To make it work, you register model like this:
admin.site.register(Activity, ActivityAdmin)
You add this code to admin.py file.

Content type dropdown not displayed django admin form

This is a Post model and when I open it in django admin to add posts, I see a field content type but there exist no drop-down to select the content type. Am I doing something wrong here?
class Post(models.Model):
FEATURE_LIMITS = models.Q(app_label=u'forums', model=u'forum')
content_type = models.ForeignKey(ContentType, limit_choices_to=FEATURE_LIMITS, on_delete=models.CASCADE)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id')
admin.py for posts
# imports
admin.site.register(posts_models.Post)
There is a model Forum, which has a generic relation with post.
class Forum(models.Model):
# other fields
posts = GenericRelation(Post)
The post field is not visible on django admin(other fields are visible).
admin.py for forums
# imports
admin.site.register(forums_models.Forum)
If I make changes to admin.py :
class PostInline(GenericTabularInline):
model = Post
class ForumAdmin(admin.ModelAdmin):
inlines = [
PostInline,
]
admin.site.register(forums_models.Forum, ForumAdmin)
Then on hitting http://localhost:8000/admin/forums/forum/add/, the page keeps loading forever.
It seems that you configured your application wrong.
My project structure
app
|-settings/
|-forums/
|--models.py
|--admin.py
|-posts/
|--models.py
|--admin.py
So posts/models.py
class Post(models.Model):
FEATURE_LIMITS = models.Q(app_label='forums', model='forum')
name = models.CharField(max_length=100)
content_type = models.ForeignKey(ContentType, limit_choices_to=FEATURE_LIMITS, on_delete=models.CASCADE)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id')
posts/admin.py
from .models import Post
class PostInline(GenericTabularInline):
model = Post
forums/models.py
class Forum(models.Model):
# other fields
name = models.CharField(max_length=100)
posts = GenericRelation('posts.Post')
forums/admin.py
from .models import Forum
from posts.admin import PostInline
#admin.register(Forum)
class ForumAdmin(admin.ModelAdmin):
inlines = [
PostInline,
]
And everything works like a charm.
I have a guess you have infinite loop because tried to register models in the wrong app.(model Forum in app posts)
I was using admin.widgets.ForeignKeyRawIdWidget widget which prevented foreign key fields to display normally. Since
content_type = models.ForeignKey(ContentType, limit_choices_to=FEATURE_LIMITS, on_delete=models.CASCADE)
content_type is a foreign key field, there was no dropdown.
To prevent this from happening, make following changes in admin.py:
class PostAdmin(admin.ModelAdmin):
raw_id_field_excludes = 'content_type'
admin.site.register(Post, PostAdmin)

Django admin - Inline with choices from database

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)")

django two ForeignKeys to same model - admin error

I have a Profiles app that has a model called profile, i use that model to extend the django built in user model without subclassing it.
models.py
class BaseProfile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, related_name='owner',primary_key=True)
supervisor = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='supervisor', null=True, blank=True)
#python_2_unicode_compatible
class Profile(BaseProfile):
def __str__(self):
return "{}'s profile". format(self.user)
admin.py
class UserProfileInline(admin.StackedInline):
model = Profile
class NewUserAdmin(NamedUserAdmin):
inlines = [UserProfileInline ]
admin.site.unregister(User)
admin.site.register(User, NewUserAdmin)
admin
the error is
<class 'profiles.admin.UserProfileInline'>: (admin.E202) 'profiles.Profile' has more than one ForeignKey to 'authtools.User'.
obviously i want to select a user to be a supervisor to another user. I think the relationship in the model is OK, the one that's complaining is admins.py file. Any idea ?
You need to use multiple inline admin.
When you have a model with multiple ForeignKeys to the same parent model, you'll need specify the fk_name attribute in your inline admin:
class UserProfileInline(admin.StackedInline):
model = Profile
fk_name = "user"
class SupervisorProfileInline(admin.StackedInline):
model = Profile
fk_name = "supervisor"
class NewUserAdmin(NamedUserAdmin):
inlines = [UserProfileInline, SupervisorProfileInline]
Django has some documentation on dealing with this: https://docs.djangoproject.com/en/1.9/ref/contrib/admin/#working-with-a-model-with-two-or-more-foreign-keys-to-the-same-parent-model
Here is an example that I have just tested to be working
class Task(models.Model):
owner = models.ForeignKey(User, related_name='task_owner')
assignee = models.ForeignKey(User, related_name='task_assigned_to')
In admin.py
class TaskInLine(admin.TabularInLine):
model = User
#admin.register(Task)
class MyModelAdmin(admin.ModelAdmin):
list_display = ['owner', 'assignee']
inlines = [TaskInLine]

Inline in Django admin: has no ForeignKey

I have two Django models:
class Author(models.Model):
user_email = models.CharField(max_length=100, blank=True)
display_name = models.CharField(max_length=250)
class Photo(models.Model):
author = models.ForeignKey(Author)
image = ThumbnailImageField(upload_to='photos')
To get inline photos, I have in admin.py:
class PhotoInline(admin.StackedInline):
model = Author
class AuthorAdmin(admin.ModelAdmin):
list_display = ('display_name','user_email')
inlines = [PhotoInline]
I get an error: Exception at /admin/metainf/author/11/
<class 'metainf.models.Author'> has no ForeignKey to <class 'metainf.models.Author'>
Why?
The inline model should be having a ForeignKey to the parent model. To get Photo as inline in Author your models code is fine. But your admin code should be as follows:
class PhotoInline(admin.StackedInline):
model = Photo
class AuthorAdmin(admin.ModelAdmin):
list_display = ('display_name','user_email')
inlines = [PhotoInline]
Read more info here.
That's because Author doesn't have a foreign key to photo. I think you need to switch the model for the inline like this:
class PhotoInline(admin.StackedInline):
model = Photo
class AuthorAdmin(admin.ModelAdmin):
list_display = ('display_name','user_email')
inlines = [PhotoInline]
Maybe you need to install django-nested-admin library, and later try with NestedStackedInline.
django-nested-admin

Categories