Neo
Neo

Reputation: 5228

django admin foreign key field data add

In add form for any app in django admin, for foreign key fields of that model.. comes a dropdown list with add button(which opens in a pop-up). Can we have a form where we can add the foreign key model fields in the same form.

For e.g

class UserProfile(models.Model):
    user = models.ForeignKey(User, unique=True)
    contact = models.ForeignKey(Contact, blank=True, null=True)

For user and contact fields a dropdown with add button is present in admin add form.Can we have all fields of user and contact in same page??

Upvotes: 31

Views: 32949

Answers (4)

Ebrahim Abdollahian
Ebrahim Abdollahian

Reputation: 618

There is a library you can use it. https://github.com/daniyalzade/django_reverse_admin

But if you want to use link to object in showing table you can like this code:

def user_link(self, obj):
    if obj.user:
        reverse_link = 'admin:%s_%s_change' % (
            obj.user._meta.app_label, obj.user._meta.model_name)
        link = reverse(reverse_link, args=[obj.user.id])
        return format_html('<a href="%s">More detail</a>' % link)
    return format_html('<span >-</span>')

user_link.allow_tags = True
user_link.short_description = 'User Info'

And in list_display:

list_display = (...,user_link,...)

Upvotes: 0

Kevin Owino
Kevin Owino

Reputation: 540

the easiest approach would be something like.

class UserProfile(models.Model):
    user = models.ForeignKey(User, unique=True)
    contact = models.ForeignKey(Contact, blank=True, null=True)


# Then in the admin create the custom admin view
from .models import Contact

class CustomAdminUserProfile(admin.ModelAdmin):
    list_display = ['contact', 'get_contact_additional_field']

    def get_contact_additional_field(self, obj):
        queryset = Contact.objects.filter(name=obj.name)[0]
        additional_field = queryset.additional_field
        return additional_field

#Then you register
admin.site.register(Contact, CustomAdminUserProfile)
        

Upvotes: 1

lynx
lynx

Reputation: 309

There's a django add-on to get inlines in cases like this where the relationship is the opposite of the usual: django_reverse_admin

You'll need to add django_reverse_admin to your requirements.txt:

-e git+https://github.com/anziem/django_reverse_admin.git#egg=django_reverse_admin

Then import it:

admin.py

from django_reverse_admin import ReverseModelAdmin

class UserProfileAdmin(ReverseModelAdmin):
    inline_reverse = ['user', 'contact']
    inline_type = 'tabular'  # or could be 'stacked'

admin.site.register(UserProfile, UserProfileAdmin)

Upvotes: 5

Darioush
Darioush

Reputation: 563

Yes, you can do that using the inline admin system.

class UserAdmin(admin.StackedInline):
    model = User
class ContactAdmin(admin.StackedInline):
    model = Contact

class UserProfileAdmin(admin.ModelAdmin):
    inlines = [ UserAdmin, ContactAdmin ]

for more details check out https://docs.djangoproject.com/en/dev/ref/contrib/admin/#inlinemodeladmin-objects .

Upvotes: 22

Related Questions