2010-04-09 32 views
11

Tôi đang tự động lưu trữ thông tin trong cơ sở dữ liệu tùy thuộc vào yêu cầu:Cách tìm hiểu xem cột của mô hình có phải là khóa ngoại không?

// table, id and column are provided by the request 
table_obj = getattr(models, table) 
record = table_obj.objects.get(pk=id) 

setattr(record, column, request.POST['value']) 

Vấn đề là request.POST [ 'giá trị'] đôi khi chứa khóa chính kỷ lục của nước ngoài (tức là một số nguyên) trong khi Django hy vọng giá trị của cột là đối tượng thuộc loại ForeignModel:

Không thể chỉ định "u'122 '": "ModelA.b" phải là phiên bản "ModelB".

Bây giờ, có cách nào thanh lịch để kiểm tra động xem b là cột chứa khóa ngoại và mô hình nào các khóa này được liên kết với? (Vì vậy mà tôi có thể tải các hồ sơ nước ngoài bởi đó là khóa chính và gán nó cho ModelA?) Hoặc không Django cung cấp thông tin như thế này để lập trình vì vậy tôi thực sự có để có được bàn tay của tôi bẩn và sử dụng isinstance() trên nước ngoài cột khóa?

Trả lời

13

Bạn có thể sử dụng get_field_by_name trên mô hình _meta đối tượng:

 

from django.db.models import ForeignKey 

def get_fk_model(model, fieldname): 
    '''returns None if not foreignkey, otherswise the relevant model''' 
    field_object, model, direct, m2m = model._meta.get_field_by_name(fieldname) 
    if not m2m and direct and isinstance(field_object, ForeignKey): 
     return field_object.rel.to 
    return None 
 

Giả sử bạn đã có một lớp mô hình MyModel bạn sẽ sử dụng này như sau:

 

fk_model = get_fk_model(MyModel, 'fieldname') 
 
+0

Đầu vào 'mô hình' sẽ không được ghi đè bởi phép gán' field_object, model_direct, m2m = ... '? – alvas

+0

Tôi đoán, nhưng nó không bao giờ được sử dụng một lần nữa vì vậy không phải là một việc lớn. –

0

Khám phá trường "ModelChoiceField". Họ có thể giải quyết vấn đề của bạn đưa chìa khóa nước ngoài vào các hình thức cho bạn hay không; thay vì tự làm điều đó.

http://docs.djangoproject.com/en/1.1/ref/forms/fields/#fields-which-handle-relationships

record = forms.ModelChoiceField(queryset=table_obj.objects.all()) 
+0

Cảm ơn, tôi sẽ làm điều đó nếu tôi không có yêu cầu đặc biệt: Tất cả "hình thức" là JS-powered inline-chỉnh sửa hình thức của tôi. Điều đó làm cho nó khá là một thách thức để tạo ra chúng với API của Django, một cái mà tôi không sẵn sàng chấp nhận. – balu

1

tôi gặp phải trường hợp sử dụng tương tự và câu trả lời được chấp nhận không hoạt động đối với tôi ectly. Tôi đang sử dụng Django 1.2 nếu nó có liên quan. Thay vào đó, tôi đã sử dụng phương thức get_field_by_name như sau.

def get_foreign_keys(self): 
     foreign_keys = [] 
     for field in self._meta.fields: 
      if isinstance(self._meta.get_field_by_name(field.name)[0], models.ForeignKey): 
       foreign_keys.append(field.name) 

     if not foreign_keys: 
      return None 
     return foreign_keys 

Đây là phương thức xác định bên trong lớp học. Đối với trường hợp của tôi, những gì tôi cần là tên của các trường ForeignKey. Chúc mừng!

1

Simple lót để tìm tất cả các mối quan hệ để models khác mà tồn tại trong một model:

In [8]: relations = [f for f in Model._meta.get_fields() if (f.one_to_many or f.one_to_one) and f.auto_created] 

Trên sẽ cung cấp cho một list của tất cả các models với relations của họ.

Ví dụ:

In [9]: relations 
Out[9]: 
[<ManyToOneRel: app1.model1>, 
<ManyToOneRel: app2.model1>, 
<OneToOneRel: app1.model2>, 
<OneToOneRel: app3.model5>, 
<OneToOneRel: app5.model1>] 
Các vấn đề liên quan