2013-06-05 3 views
0

벽에 머리를 다시 당깁니다. 본인은 알려진 필드 save()에서 RelatedManager add() 메서드를 사용하는 방법

# models.py 
class MyModel(models.Model): 
    ... 
    tags = models.ManyToManyField(Tag, blank=True) 
    field_m2m = models.ManyToManyField('M2mModel', blank=True) 
    field_fk = models.ForeignKey('FkModel', blank=True, null=True) 
    ... 
    def save(self, *args, **kwargs): 
     for inst in self.field_m2m.all(): 
      self.tags.add(Tag.objects.get(name=inst.name)) 
     self.tags.add(Tag.objects.get(name=self.field_fk.name)) 
     super(MyModel, self).save(*args, **kwargs) 

class FkModel(models.Model): 
    name = models.CharField(max_length=255, unique=True) 
    ... 

class M2mModel(models.Model): 
    name = models.CharField(max_length=255, unique=True) 
    ... 

나는 100 % 확신 내 field_m2m 오전를 사용하여 태그를 추가하려고하고 빈 field_fk없는 어떤 덜 중요하지 해요 : 기존 태그에 해당하는 경우가있다. 이 부분을 잘 다루는 다른 기능이 있습니다. 나는 또한 문자열 ( Tag.objects.get(name="mystring"))을 하드 코딩하여 101 %를 확실하게 시도했다.

그러나 관리자 패널을 통해 태그가 지정되지 않았습니다. 나는 쉘의 단계를 거치려고 노력했고 거기에서 작동한다.

>>> m = MyModel.objects.get(name='something') 
>>> t = Tag.objects.get(name='sometag') 
>>> m.tags.add(t) 
>>> m.tags.all() 
[<Tag: sometag>] 

save() 메소드를 사용하려면 어떻게해야하나요? 내가 모델 인스턴스를 저장해야합니다 생각 "<MyModel: Something>" needs to have a value for field "mymodel" before this many-to-many relationship can be used.

도 오른쪽 상기 과제를 수행하기 전에 다음 모델 인스턴스가 처음 생성 될 때까지

또한, 역 추적 대해 불평? 한 번에 모든 것을 어떻게 할 수 있습니까?

답변

0

이 힌트로 인해 이것을 알았습니다. https://stackoverflow.com/a/6200451/1344854
모델 save() 메소드는 기본값으로 유지됩니다. 먼저 FkModel 및 M2mModel 인스턴스에 태그를 연결했습니다. 나머지 작업은 ModelAdmin에서 수행됩니다.

# models.py 
class FkModel(models.Model): 
    name = models.CharField(max_length=255, unique=True) 
    tag = models.ForeignKey(Tag, blank=True, null=True, related_name='fk') 
    ... 

class M2mModel(models.Model): 
    name = models.CharField(max_length=255, unique=True) 
    tag = models.ForeignKey(Tag, blank=True, null=True, related_name='m2m') 
    ... 

# admin.py 
class MyModelAdmin(admin.ModelAdmin): 
    def save_model(self, request, obj, form, change): 
     form.save() # as I learned, without saving at this point, obj.field_m2m.all() will be empty 
     tags = [] 
     if obj.field_m2m.all(): 
      tags += [m2m.tag for m2m in obj.field_m2m.all()] 
     if obj.field_fk: 
      tags += [obj.field_fk.tag] 
     form.cleaned_data['tags'] = tags 
     super(MyModelAdmin, self).save_model(request, obj, form, change) 
1

관계를 저장하기 전에 MyModel 인스턴스를 데이터베이스에 저장해야합니다. 관계에 대해 MyModel의 ID가 필요하기 때문에 의미가 있습니다. 그래서 당신은이 같은 save 방법의 순서를 변경할 수 있습니다

def save(self, *args, **kwargs): 
    # notice that super class save go first. 
    super(MyModel, self).save(*args, **kwargs) 
    # also this cicle doesn't make sense since self is a newly 
    # created instance so it won't have anythin in field_m2m.all() 
    for inst in self.field_m2m.all(): 
     self.tags.add(Tag.objects.get(name=inst.name)) 
    # this should work ok if get returns any tag. 
    self.tags.add(Tag.objects.get(name=self.field_fk.name)) 

희망이 도움이!

+0

감사합니다. 두 번째 문제에 도움이됩니다. 여전히 태그를 할당 할 수 없습니다. – gwaramadze

+0

미안하지만 문제가 아주 커, 첫 번째 문제는 무엇입니까? 나는 그것을 찾을 수 없으며, 당신은 더 구체적으로 편집 할 수 있습니까? –

+0

당신이 제공 한 snipped에서 super 아래의 부분은 결과를 가져 오지 않습니다. self.tags.add는 아무 것도 추가하지 않습니다 – gwaramadze