2017-01-26 4 views
0

Я работаю над удалением существующих отношений GenericForeignKey из некоторых моделей. Id хотел бы изменить его на реформатрованную модель ниже. Могут ли миграции обеспечить способ преобразования существующих content_type и object_ids в соответствующие новые ForeignKey? (для сохранения существующих данных). В принципе совершенно новый при программировании, так простите меня, если я задам глупый вопрос.Django: Преобразование отношения GenericForeignKey к отношениям ForeignKey

class Donation(models.Model): 
    amount_id = models.CharField(max_length=12, unique=True, editable=False) 
    date_issued=models.DateField(auto_now_add=True) 
    description=models.TextField(blank=True, null=True) 

    content_type = models.ForeignKey(ContentType) 
    object_id = models.PositiveIntegerField() 
    content_object = generic.GenericForeignKey('content_type','object_id') 

class Individual(BaseModel): 
    first_name = models.CharField(max_length=50) 
    middle_name = models.CharField(max_length=50, blank=True, 
    null=True) 
    last_name = models.CharField(max_length=50) 
    suffix = models.CharField(max_length=50, blank=True, null=True) 
    contributor = generic.GenericRelation(Donation, related_query_name='individual') 


class Organization(models.Model): 
    name = models.CharField(max_length=100) 
    contributor = generic.GenericRelation(Donation, related_query_name='organization') 

Измененной Модель

class Donation(models.Model): 
    amount_id = models.CharField(max_length=12, unique=True, editable=False) 
    date_issued=models.DateField(auto_now_add=True) 
    description=models.TextField(blank=True, null=True) 

    contributor_group = models.ForeignKey(Organization, null=True, blank=True, on_delete=models.CASCADE) 
    contributor_individual = models.ForeignKey(Individual, null=True, blank=True, on_delete=models 

ответ

0

на основе вашей модели определения Благотворительной модели, одна из полого contributor_group, contributor_model всегда будет Null после миграции. Надеюсь, вы приняли это во внимание.

Просто, чтобы быть в безопасности Сделайте это в две фазы. 1. Сохраните content_type и object_id и добавьте два новых поля. 2. В следующем шаге удалите совокупность данных общего профиля.

Есть два способа населяющих эти новые поля

  1. Джанго Миграция предоставляет вам возможность заселить новые поля со значениями во время миграций. Вы можете посмотреть его. Я еще этого не делал.

  2. Для большего контроля и обучения. Вы можете заполнить это и с помощью скриптов. Вы можете настроить модуль django-extensions в своем проекте. И напишите сценарий, чтобы сделать это для вас. Пример сценария будет выглядеть.

    из myproject.models импорта Пожертвование, Individual, Организация из django.contrib.contenttypes.models импорта ТипСодержимого

    Защиту запустить(): organization_content_type = ContentType.objects.get_for_model (Организация) individual_content_type = ContentType. obejcts.get_for_model (Individual)

    donations = Donation.objects.all() 
    for donation in donations: 
        if donation.content_type_id == organization_content_type.id: 
          donation.contributor_group = donation.object_id 
        elif donation.content_type_id == individual_content_type.id: 
          donation.contributor_individual = donation.object_id 
        else: 
          print "Can't identify content type for donation id {}".format(donation.id) 
        donation.save() 
    

Проверьте значения являются правильными, а затем удалить общие поля. Опасаясь некоторых проблем с форматированием здесь.