Editing both sides of M2M in Admin Page

2024/10/13 11:20:27

First I'll lay out what I'm trying to achieve in case there's a different way to go about it!

I want to be able to edit both sides of an M2M relationship (preferably on the admin page although if needs be it could be on a normal page) using any of the multi select interfaces.

The problem obviously comes with the reverse side, as the main side (where the relationship is defined) works just fine automagically.

I have tried some of the advice here to get an inline to appear and that works but its not a very nice interface.

The advice I got on the django mailing list was to use a custom ModelForm. I've got as far as getting a multiselect box to appear but it doesnt seem to be "connected" to anything as it does not start with anything selected and does not save any changes that are made.

Here's the appropriate snippets of code:

#models.py
class Tag(models.Model):name = models.CharField(max_length=200)class Project(models.Model):name = models.CharField(max_length=200)description = models.TextField()tags = models.ManyToManyField(Tag, related_name='projects')#admin.py
class TagForm(ModelForm):fields = ('name', 'projects')projects = ModelMultipleChoiceField(Project.objects.all(), widget=SelectMultiple())class Meta:model = Tagclass TagAdmin(admin.ModelAdmin):fields = ('name', 'projects')form = TagForm

Any help would be much appreciated, either getting the code above to work or by providing a better way to do it!

DavidM

Answer

The reason why nothing happens automatically is that the "projects" field is not a part of the Tag model. Which means you have to do all the work yourself. Something like (in TagForm):

def __init__(self, *args, **kwargs):super(TagForm, self).__init__(*args, **kwargs)if 'instance' in kwargs:self.fields['projects'].initial = self.instance.project_set.all()def save(self, *args, **kwargs):super(TagForm, self).save(*args, **kwargs)self.instance.project_set.clear()for project in self.cleaned_data['projects']:self.instance.project_set.add(project)

Note that the code is untested so you might need to tweek it some to get it to work.

https://en.xdnf.cn/q/69538.html

Related Q&A

unstacking shift data (start and end time) into hourly data

I have a df as follows which shows when a person started a shift, ended a shift, the amount of hours and the date worked. Business_Date Number PayTimeStart PayTimeEnd Hours 0 2019-05-24 1…

Tensorflow model prediction is slow

I have a TensorFlow model with a single Dense layer: model = tf.keras.Sequential([tf.keras.layers.Dense(2)]) model.build(input_shape=(None, None, 25))I construct a single input vector in float32: np_ve…

Pandas Sqlite query using variable

With sqlite3 in Python if I want to make a db query using a variable instead of a fixed command I can do something like this :name = MSFTc.execute(INSERT INTO Symbol VALUES (?) , (name,))And when I tr…

How to remove ^M from a text file and replace it with the next line

So suppose I have a text file of the following contents:Hello what is up. ^M ^M What are you doing?I want to remove the ^M and replace it with the line that follows. So my output would look like:Hello…

Cython: size attribute of memoryviews

Im using a lot of 3D memoryviews in Cython, e.g.cython.declare(a=double[:, :, ::1]) a = np.empty((10, 20, 30), dtype=double)I often want to loop over all elements of a. I can do this using a triple loo…

python asynchronous httprequest

I am trying to use twitter search web service in python. I want to call a web service like:http://search.twitter.com/search.json?q=blue%20angels&rpp=5&include_entities=true&result_type=mix…

What are response codes for 256 and 512 for os.system in python scripting

When i ping servers with os.system in python i get multiple response codes. Command used - os.system("ping -q -c 30 -s SERVERANME")0 - Online 256 - Offline 512 - what does 512 mean ?

Sphinx floating point formatting

Im using Sphinx to generate documentation from code. Does anyone know if there is a way to control the formatting of floating point numbers generated from default arguments. For example if I have the f…

Truncating column width in pandas

Im reading in large csv files into pandas some of them with String columns in the thousands of characters. Is there any quick way to limit the width of a column, i.e. only keep the first 100 characters…

Django - CreateView with multiple models

Can I use Django CreateViews to make a form that add data to multiple tables? Ive created a model called UserMeta to store some additional informations of my users. The ProblemI want to create a view …