Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding a ManyToManyWidget to the reverse of a ManyToManyField in the Django Admin

Let's say I have a simple blog app in Django 1.4:

class Post(models.Model):     title = …     published_on = …     tags = models.ManyToManyField('Tag')  class Tag(models.Model):     name = … 

i.e. a post has many tags. On the Django admin, I get a nice little <select multi> if I include tags in the fields for the PostAdmin. Is there an easy way to include the list of the posts (as a simple <select multi>) in the TagAdmin? I tried putting fields = ['name', 'posts'] in the TagAdmin and got an ImproperlyConfigured error. (same result for post_set).

I'm alright with Django, so could whip up a proper AdminForm and Admin object, but I'm hoping there a Right Way™ to do it.

like image 563
Amandasaurus Avatar asked Mar 26 '12 20:03

Amandasaurus


People also ask

What is admin Modeladmin in Django?

One of the most powerful parts of Django is the automatic admin interface. It reads metadata from your models to provide a quick, model-centric interface where trusted users can manage content on your site. The admin's recommended use is limited to an organization's internal management tool.

What is Prepopulated_fields in Django admin?

The attribute prepopulated_fields tells the admin application to automatically fill the field slug - in this case with the text entered into the name field.

How do I make administrative superuser in Django?

Django's “Hello World” application Start the terminal by clicking on the “Run” button. Type python3 manage.py createsuperuser in the given terminal and press “Enter”. The system will ask for credentials, after which a superuser will be created. To run the server, we type the command python3 manage.py runserver 0.0.

What is manytomanyfield in Django?

ManyToManyField s confuse a lot of people. The way you relate objects to each other using a many-to-many relationship is just different enough from dealing with ForeignKey s and just uncommon enough in day-to-day Django development that it's easy to forget all the little tricks for dealing with them.

How does a many-to-many relationship work in Django?

Unfortunately the way Django deals with this is a bit unintuitive and can be confusing, so I thought it would be best to demonstrate how a many to many relationship works under the hood. To maintain a many-to-many relationship between two tables in a database, the only way is to have a third table which has references to both of those tables.

How do I use many to many in Django?

ManyToMany. A ManyToMany field is used when a model needs to reference multiple instances of another model. Use cases include: In this case, the user needs to be able to add multiple members to a meal. If the choices were fixed and the same for every user, then we could use django-multiple-select-field.

Why does my manytomanyfield reference a Target Field as a set?

This is because Django internally references a target ManyToManyField as a set. This behaviour can be overridden by providing a related_name option to the target field. class Sandwich ( models. Model ): name = models. CharField ( max_length=100) sauces = models. ManyToManyField ( Sauce, related_name="sandwiches")


1 Answers

This is possible to do with a custom form.

from django.contrib import admin from django import forms  from models import Post, Tag  class PostAdminForm(forms.ModelForm):     tags = forms.ModelMultipleChoiceField(         Tag.objects.all(),         widget=admin.widgets.FilteredSelectMultiple('Tags', False),         required=False,     )      def __init__(self, *args, **kwargs):         super(PostAdminForm, self).__init__(*args, **kwargs)         if self.instance.pk:             self.initial['tags'] = self.instance.tags.values_list('pk', flat=True)      def save(self, *args, **kwargs):         instance = super(PostAdminForm, self).save(*args, **kwargs)         if instance.pk:             instance.tags.clear()             instance.tags.add(*self.cleaned_data['tags'])         return instance  class PostAdmin(admin.ModelAdmin):     form = PostAdminForm  admin.site.register(Post, PostAdmin) 

That False in there can be replaced with a True if you want vertically stacked widget.

like image 70
Matthew Schinckel Avatar answered Oct 16 '22 02:10

Matthew Schinckel