Add element in many to many field and preserve order

Viewed 77
class Country(Models.Model):
    code = models.CharField(max_length=50)
    name = models.CharField(max_length=500)

    class Meta:
        unique_together = (('code', 'name'),)
        db_table = 'md_country'


class UserSettings(models.Model):
        ...
                                                  
        default_countries = models.ManyToManyField(Country, db_table='user_default_countries', related_name='default_countries')

I have two models inside django models, what im trying is when i add Country models to default_countries i want to preserve order. Currently when i append manytomany field django automatically sort by Country name (alphabetical order)

I have this code

# iterate one by one to preserve fetching order
country_models = [Country.objects.get(id=_id) for _id in request.data[default_countries]]
user_settings.default_countries.clear()
for c in country_models:
    user_settings.default_countries.add(c)

After this when i inspect user_settings.default_countries i have ordered countries by name in alphabetical order.

I want to preserve when adding element. If i want to add France and Australia and i order the list like that i on the end when i pull data from db i want it to be ordered like that. Now on this example i have Australia then France.

EDIT:

I checked the database and when inserting the data, it insert in right order enter image description here

For example if i want France(73) then Australia(13), France has smaller id so its inserted first. There is a problem with django when pulling the data from database.

2 Answers

So as I understand correct you want to sort by insert order:

someSetting = UserSettings.objects.first()
countries = someSetting.default_countries.order_by('id')

I found the workaround.

Firstly i defined new property inside model where default_countries is.

@property
def ordered_default_countries(self):
    return self.default_countries.all().order_by('-id')

Then in serializer where i serialize this field i just pointed default_countries field to ordered_default_countries.

Related