`Rel_name` được sử dụng trong Django là gì?


391

Là gì related_nametranh luận hữu ích cho trên ManyToManyFieldForeignKeycác lĩnh vực? Ví dụ, cho mã sau đây, tác dụng của là related_name='maps'gì?

class Map(db.Model):
    members = models.ManyToManyField(User, related_name='maps',
                                     verbose_name=_('members'))

12
@DanielRoseman Bằng cách nào đó tốt cho hiệu suất hoặc thực hành tốt để sử dụng có liên quan_name = '+' khi không cần thiết quan hệ ngược?
lajarre

10
Tôi tò mò muốn biết câu trả lời cho câu hỏi của @ lajarre.
3cheesewheel

1
@lajarre - Tôi cho rằng sẽ không thay đổi hiệu suất. Tôi đã phải sử dụng nó một lần với các loại nội dung FeinCMS. Cá nhân tôi nghĩ rằng đó là cách thực hành tốt để luôn chỉ định related_namevì vậy nếu bạn biết bạn sẽ không sử dụng nó, tôi đoán đó là một điều tốt. Tất nhiên đó là ý kiến ​​cá nhân.
François Constant

@ 3cheesewheel bây giờ trong tài liệu: docs.djangoproject.com/en/2.0/ref/models/fields/ cảm + có nghĩa là không tạo quan hệ ngược
P. Myer Nore

Câu trả lời:


531

Các related_namethuộc tính chỉ định tên của mối quan hệ ngược từ Usermô hình lại mô hình của bạn.

Nếu bạn không chỉ định related_name, Django tự động tạo ra một cách sử dụng tên của mô hình của bạn với các hậu tố _set, ví dụ User.map_set.all().

Nếu bạn làm chỉ định, ví dụ như related_name=mapstrên Usermô hình, User.map_setvẫn sẽ làm việc, nhưng các User.maps.cú pháp rõ ràng là một chút bụi và ít phiền phức; vì vậy, ví dụ, nếu bạn có một đối tượng người dùng current_user, bạn có thể sử dụng current_user.maps.all()để lấy tất cả các phiên bản của Mapmô hình có liên quan đến current_user.

Các tài liệu Django có thêm chi tiết.


1
Được rồi, tôi biết đây là một bài viết cũ. Nhưng tôi chỉ đang cố gắng để tìm ra điều này - mẹo + ở cuối tên liên quan là gì? Ví dụ, điều gì xảy ra nếu tôi làm related_name='maps+'trong ví dụ trên?
Sidd

10
nếu bạn thêm +, django sẽ vô hiệu hóa ánh xạ
josephmisiti

5
đối với OneToOneField mặc định có liên quan_name sẽ là tên lớp trường hợp nhỏ. Ví dụ trong ví dụ đã cho nếu các thành viên sẽ là OneToOnefield thì "User.map" sẽ hoạt động.
ancho

nếu bạn chỉ định related_name, _setvẫn hoạt động trong django1.11 >??
Esir Kings

9
Tôi sử dụng Django 2.1.3 và tôi có thể lưu ý những thứ đó là độc quyền. Một khi related_nameđược chỉ định, _setkhông hoạt động nữa.
stockersky

84

Để thêm vào câu trả lời hiện có - tên liên quan là bắt buộc trong trường hợp có 2 FK trong mô hình trỏ đến cùng một bảng. Ví dụ trong trường hợp Bill vật liệu

@with_author 
class BOM(models.Model): 
    name = models.CharField(max_length=200,null=True, blank=True)
    description = models.TextField(null=True, blank=True)
    tomaterial =  models.ForeignKey(Material, related_name = 'tomaterial')
    frommaterial =  models.ForeignKey(Material, related_name = 'frommaterial')
    creation_time = models.DateTimeField(auto_now_add=True, blank=True)
    quantity = models.DecimalField(max_digits=19, decimal_places=10)

Vì vậy, khi bạn sẽ phải truy cập dữ liệu này, bạn chỉ có thể sử dụng tên liên quan

 bom = material.tomaterial.all().order_by('-creation_time')

Nó không hoạt động khác (ít nhất là tôi đã không thể bỏ qua việc sử dụng tên liên quan trong trường hợp 2 FK vào cùng một bảng.)


2
Bạn phải chọn một tên liên quan ít nhất cho một trong số họ. Một cái khác không cần thiết phải yêu cầu.
Csaba Toth

32
related_namenên số nhiều. Bởi vì quan hệ ForeignKey trả lại nhiều đối tượng.
Mesut Tasci

11

Đối related_namesố cũng hữu ích nếu bạn có các tên lớp liên quan phức tạp hơn. Ví dụ: nếu bạn có mối quan hệ khóa ngoại:

class UserMapDataFrame(models.Model):
    user = models.ForeignKey(User) 

Để truy cập UserMapDataFramecác đối tượng từ các liên quan User, cuộc gọi mặc định sẽ làUser.usermapdataframe_set.all() điều khá khó đọc.

Sử dụng related_namecho phép bạn chỉ định một tên đơn giản hơn hoặc dễ đọc hơn để có được mối quan hệ ngược lại. Trong trường hợp này, nếu bạn chỉ định user = models.ForeignKey(User, related_name='map_data'), cuộc gọi sẽ là User.map_data.all().


3

Tham số tên liên quan thực sự là một tùy chọn. Nếu chúng ta không thiết lập nó, Django sẽ tự động tạo ra mặt khác của mối quan hệ với chúng ta. Trong trường hợp của mô hình Bản đồ, Django sẽ tạo một map_setthuộc tính, cho phép truy cập thông qua m.map_settrong ví dụ của bạn (m là thể hiện lớp của bạn). Công thức Django sử dụng là tên của mô hình theo sau là chuỗi _set. Do đó, tham số tên liên quan chỉ đơn giản ghi đè mặc định của Django thay vì cung cấp hành vi mới.


0

prefetch_relatedsử dụng cho dữ liệu tìm nạp trước cho nhiều đến nhiều và nhiều dữ liệu quan hệ. select_relatedlà chọn dữ liệu từ một mối quan hệ giá trị duy nhất. Cả hai đều được sử dụng để lấy dữ liệu từ các mối quan hệ của chúng từ một mô hình. Ví dụ: bạn xây dựng một mô hình và một mô hình có mối quan hệ với các mô hình khác. Khi có yêu cầu, bạn cũng sẽ truy vấn dữ liệu mối quan hệ của họ và Django có cơ chế rất tốt Để truy cập dữ liệu từ mối quan hệ của họ như thế book.author.namenhưng khi bạn lặp lại danh sách các mô hình để tìm nạp dữ liệu mối quan hệ của họ, Django tạo từng yêu cầu cho mỗi dữ liệu mối quan hệ. Để khắc phục điều này, chúng tôi có prefetchd_relatedselected_related

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.