2012-02-16 41 views
36

Cách tốt nhất để đặt giá trị mặc định cho trường khóa ngoài trong mô hình là gì? Giả sử tôi có hai mô hình, sinh viên và thi với sinh viên có exam_taken là khóa nước ngoài. Làm thế nào tôi lý tưởng sẽ thiết lập một giá trị mặc định cho nó? Đây là nhật ký nỗ lực của tôiĐặt giá trị mặc định cho thuộc tính khóa ngoài

class Student(models.Model): 
    .... 
    ..... 
    exam_taken = models.ForeignKey("Exam", default=1) 

Làm việc, nhưng có linh cảm có cách tốt hơn.

def get_exam(): 
    return Exam.objects.get(id=1) 

class Student(models.Model): 
    .... 
    ..... 
    exam_taken = models.ForeignKey("Exam", default=get_exam) 

Từ here, nhưng không thành công với bảng không tồn tại lỗi khi đồng bộ hóa.

Mọi trợ giúp sẽ được đánh giá cao.

+0

làm thế nào về: http://stackoverflow.com/questions/937954/how-do-you-specify-a-default-for-a-django-foreignkey-model-or-adminmodel-field –

+2

@TomIngram no it không nên! – balazs

+0

@NitzanTomer Nó dành cho một AdminModelField. Đã nhìn thấy nó trước đó. – primpap

Trả lời

18

Trong cả hai ví dụ của bạn, bạn đang mã hóa cứng id của phiên bản mặc định. Nếu điều đó là không thể tránh khỏi, tôi chỉ cần đặt một hằng số.

DEFAULT_EXAM_ID = 1 
class Student(models.Model): 
    ... 
    exam_taken = models.ForeignKey("Exam", default=DEFAULT_EXAM_ID) 

Ít mã hơn và đặt tên hằng số giúp dễ đọc hơn.

+0

Tôi nhận được lỗi sau: 'TypeError: Đối số bổ sung nên được đặt tên _ , có 'default'' Với mã: 'category_id = db.Column (db.Integer, db.ForeignKey (" category.id ", default = 1), primary_key = True)' Bạn có thể vui lòng trợ giúp? – ChickenFeet

+0

BTW có hai PK, vì vậy khóa sẽ vẫn là duy nhất. – ChickenFeet

6

tôi sử dụng các phím tự nhiên để áp dụng một cách tiếp cận tự nhiên hơn:

<app>/models.py

from django.db import models 

class CountryManager(models.Manager): 
    """Enable fixtures using self.sigla instead of `id`""" 

    def get_by_natural_key(self, sigla): 
     return self.get(sigla=sigla) 

class Country(models.Model): 
    objects = CountryManager() 
    sigla = models.CharField(max_length=5, unique=True) 

    def __unicode__(self): 
     return u'%s' % self.sigla 

class City(models.Model): 
    nome = models.CharField(max_length=64, unique=True) 
    nation = models.ForeignKey(Country, default='IT') 
+2

Tôi đã thử điều này trong Django 1.6 nhưng tôi nhận được lỗi, "Không hợp lệ chữ cho int() với cơ sở 10: 'IT'. (Chuỗi của tôi là khác nhau, nhưng bạn có được ý tưởng.) – Seth

+2

Điều này làm việc tốt, mặc dù, và có vẻ thêm Pythonic: 'default = lambda: Country.objects.filter (sigla = 'IT'). first()' – Seth

+0

Lạ, tôi nhớ đã thử nghiệm điều này với django 1.6. Googling Tôi tìm thấy nó là một vấn đề tuple, hãy thử: 'def get_by_natural_key (self, sigla): return (self.get (sigla = sigla),) 'hoặc cũng với' default = ('IT',) '. Tôi chỉ đoán thôi;) – vault

2

Bạn có thể sử dụng mô hình này:

class Other(models.Model): 
    DEFAULT_PK=1 
    name=models.CharField(max_length=1024) 

class FooModel(models.Model): 
    other=models.ForeignKey(Other, default=Other.DEFAULT_PK) 

Tất nhiên bạn cần phải chắc chắn rằng có một hàng trong bảng của Other. Bạn nên sử dụng một datamigration để chắc chắn nó tồn tại.

1

Trong trường hợp của tôi, tôi muốn đặt mặc định thành phiên bản hiện tại của mô hình liên quan. Bởi vì nó có thể là Exam với id 1 đã bị xóa, tôi đã thực hiện như sau:

class Student(models.Model): 
    exam_taken = models.ForeignKey("Exam", blank=True) 

    def save(self, *args, **kwargs): 
     try: 
      self.exam_taken 
     except: 
      self.exam_taken = Exam.objects.first() 
     super().save(*args, **kwargs) 

Nếu exam_taken không tồn tại, django.db.models.fields.related_descriptors.RelatedObjectDoesNotExist sẽ được nâng lên khi một cố gắng truy cập vào nó.

Các vấn đề liên quan