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.
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.
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.
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.
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.
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.
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.
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")
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With