2011-05-23 13 views
9

Mam obsługi modelu profil z pola M2MManyToManyField i Południowej migracja

class Account(models.Model): 
    ... 
    friends = models.ManyToManyField('self', symmetrical=True, blank=True) 
    ... 

Teraz muszę wiedzieć, jak i kiedy dodać siebie jako znajomego I stworzył model dla tego

class Account(models.Model): 
    ... 
    friends = models.ManyToManyField('self', symmetrical=False, blank=True, through="Relationship") 
    ... 


class Relationship(models.Model):  
    """ Friends """   
    from_account = models.ForeignKey(Account, related_name="relationship_set_from_account")    
    to_account = models.ForeignKey(Account, related_name="relationship_set_to_account") 
    # ... some special fields for friends relationship 

    class Meta:      
     db_table = "accounts_account_friends"    
     unique_together = ('from_account','to_account') 

Czy należy utworzyć migrację dla tych zmian, czy nie? Jeśli masz jakieś sugestie, nie krępuj się, napisz tutaj.

Dzięki

PS: accounts_account tabela zawiera już zapisy

Odpowiedz

8

Po pierwsze, unikam używania aliasu db_table, jeśli potrafisz. Utrudnia to zrozumienie struktury tabeli, ponieważ nie jest już zsynchronizowana z modelami.

Po drugie, interfejs API South oferuje funkcje takie jak db.rename_table(), z których można korzystać ręcznie, edytując plik migracji. Możesz zmienić nazwę tabeli accounts_account_friends na accounts_relation (jak Django domyślnie nazwałby to) i dodać dodatkowe kolumny.

To w połączeniu daje następującą migracją:

def forwards(self, orm): 
    # the Account.friends field is a many-to-many field which got a through= option now. 
    # Instead of dropping+creating the table (or aliasing in Django), 
    # rename it, and add the required columns. 

    # Rename table 
    db.delete_unique('accounts_account_friends', ['from_account', 'to_account']) 
    db.rename_table('accounts_account_friends', 'accounts_relationship') 

    # Add extra fields 
    db.add_column('accounts_relationship', 'some_field', ...) 

    # Restore unique constraint 
    db.create_unique('accounts_relationship', ['from_account', 'to_account']) 


def backwards(self, orm): 

    # Delete columns 
    db.delete_column('accounts_relationship', 'some_field') 
    db.delete_unique('accounts_relationship', ['from_account', 'to_account']) 

    # Rename table 
    db.rename_table('accounts_relationship', 'accounts_account_friends') 
    db.create_unique('accounts_account_friends', ['from_account', 'to_account']) 


models = { 
    # Copy this from the final-migration.py file, see below 
} 

Wyjątkowa relacja jest usuwany i odtworzono więc ograniczenie ma właściwą nazwę.

Sprawozdania kolumna ADD są łatwo generowane z następującą sztuczkę:

  • Dodaj model Relationship w models.py tylko kluczowych dziedzinach obcych, a nie zmiany w zakresie M2M jeszcze.
  • Migracja do niego
  • Dodaj pola do modelu Relationship.
  • Wykonaj ./manage.py schemamigration app --auto --stdout | tee final-migration.py | grep column
  • Przywróć pierwszą migrację.

Następnie masz wszystko, czego potrzeba do utworzenia pliku migracji.

+0

Dziękujemy za odpowiedź – srusskih

+0

@sussih: chętnie słuchać! – vdboor

1

Droga masz to zakodowane tam, jesteś ręcznego definiowania modelu, który robi to samo zadanie jak M2M dołączyć tabelę Django automatycznie stworzyłem dla ciebie. Rzecz w tym, że automatycznie utworzony stół będzie się nazywał accounts_relationship_friend.

To, co tam robisz, utworzy model, który spróbuje zduplikować to, co ORM zrobił pod powierzchnią, ale wskazuje na niewłaściwą tabelę.

Jeśli nie potrzebujesz jawnego modelu łączenia, zostawiłbym go usunąć z bazy kodów i nie utworzyd migracji, aby go dodać, a zamiast tego użyj M2M, aby znaleźć relacje między przyjaciółmi. (Nie myślę o tym zbyt głęboko, ale powinno działać).

Jeśli jednak chcesz zrobić coś specjalnego w modelu relacji, który masz (np. Przechowywać atrybuty dotyczące rodzaju relacji, itp.), Zadeklarowałbym model relacji, aby był to model przez Ciebie używany w Twoim Przyjacielu. definicja znajomych m2m. See the docs here.

+0

Mam model z m2m pole 'friends' i istnieją profile w DB. Teraz chcę dodać specjalną właściwość do statku relacji (data utworzenia, itp.). I tworzę tabelę "koryta". I chcę wiedzieć: czy powinienem przeprowadzić migrację dla tego przypadku. Twoja odpowiedź zawiera dobre informacje, ale jak widać, już to zrobiłem. – srusskih