2012-10-17 27 views
6

Lưu ý: Tôi đã kể từ asked this question again được cập nhật cho mô hình người dùng của Django kể từ phiên bản 1.5.Cách thiết lập mô hình Django với hai loại người dùng với các thuộc tính rất khác nhau

Tôi đang xây dựng lại và cải tiến trang web Django đã có và chuyển từ Webfaction sang Heroku và từ SimpleDB của Amazon sang Heroku Postgres (mặc dù thử nghiệm cục bộ trên Sqllite3 khi phát triển). Rất nhiều những gì tôi đang làm là chuyển sang sử dụng chức năng Django tích hợp, như quản trị viên Django, xác thực người dùng, v.v.

Về mặt khái niệm, trang web có hai loại người dùng: Sinh viên và doanh nghiệp. Hai loại người dùng có các quyền và thông tin hoàn toàn khác nhau được lưu trữ về chúng. Đây là rất nhiều trường hợp mà trong cấu trúc ban đầu của trang web, chúng tôi thiết lập mô hình dữ liệu như sau:

Users 
    ID (primary_key) 
    Business_or_Student ('B' if business, 'S' if student) 
    email (unique) 
    password (hashed, obviously) 
    ... 

Students 
    ID (Foreignkey on Users) 
    <more information> 
    ... 

Businesses 
    ID (Foreignkey on Users) 
    <more information> 
    ... 

này làm việc khá tốt đối với chúng tôi, và chúng tôi đã có thông tin người dùng bare-xương ở những người sử dụng bảng, và sau đó bất kỳ thông tin chi tiết hơn trong bảng học sinh và doanh nghiệp. Bắt một lý lịch thành viên đầy đủ yêu cầu cái gì đó dọc giả này:

def get_user_profile(id): 
    if Users(id=id).Business_or_Student = 'B': 
     return Businesses(id=id) 
    else: 
     return Students(id=id) 

Trong di chuyển qua, tôi đã phát hiện ra rằng chức năng khá hạn chế xây dựng trong User đối tượng có Django, và tôi đã có để mở rộng nó với một lớp UserProfile Tôi đã tạo và sau đó có thêm các bảng StudentBusiness. Với tất cả các bản vá tôi đang làm với điều này trong quản trị Django, và tương đối xa lạ với các mô hình Django vì tôi luôn làm điều đó một cách khác nhau, tôi không chắc đây có phải là cách tốt nhất để đi hay không. chỉ cần gắn tất cả thông tin cho doanh nghiệp và sinh viên trong bảng UserProfile và chỉ phân biệt hai nhóm với các nhóm khác nhau hoặc thậm chí có một số cách để thực hiện việc này trong đối tượng được xây dựng trong User.

Vì doanh nghiệp và sinh viên cũng có giao diện khác nhau, tôi nghiêm túc cân nhắc việc thiết lập hai ứng dụng khác nhau trong dự án Django của tôi và tách biệt quan điểm, mô hình, v.v. Điều đó sẽ trông giống như sau:

MyProject/ 
    MyProject/ (project folder, Django 1.4) 
    mainsite/ 
    students/ 
    businesses/ 

Một trong những mối quan tâm lớn nhất của tôi là với Quản trị viên Django. Trong việc mở rộng User, tôi đã có thêm đoạn mã sau:

class UserProfileInline(admin.StackedInline): 
    model = UserProfile 
    can_delete = False 
    verbose_name_plural = 'profile' 

class UserAdmin(UserAdmin): 
    inlines = (UserProfileInline,) 

Tuy nhiên, tôi muốn thông tin cho các khía cạnh kinh doanh hoặc sinh viên của người sử dụng để hiển thị trong admin Django khi đó User được kéo lên, nhưng ForeignKey một phần của mô hình này là trong mô hình StudentBusiness vì mỗi Student/BusinessUser nhưng mỗi User chỉ có một Studenthay một Business đối tượng kết nối với nó. Tôi không chắc cách thêm Dòng nội tuyến có điều kiện cho Quản trị viên.

Câu hỏi: Với cấu trúc này và những mối quan tâm này, cách tốt nhất để thiết lập trang web này, đặc biệt là mô hình dữ liệu là gì?

Trả lời

5

Đây không phải là giải pháp hoàn chỉnh, nhưng nó sẽ cung cấp cho bạn ý tưởng về nơi bắt đầu.

  • Tạo mẫu UserProfile trong mainsite. Điều này sẽ giữ bất kỳ thuộc tính phổ biến nào cho cả hai loại người dùng. Liên hệ với mô hình User với trường OneToOne(...).
  • Tạo hai mô hình khác trong mỗi ứng dụng, (sinh viên/doanh nghiệp), BusinessStudent, trong đó có OneToOne mối quan hệ với mỗi UserProfile (hoặc kế thừa từ UserProfile). Điều này sẽ giữ các thuộc tính cụ thể cho loại người dùng đó. Tài liệu: Multitable inheritance/OneToOne Relationships
  • Bạn có thể thêm trường trong UserProfile để phân biệt xem đó là hồ sơ của doanh nghiệp hay sinh viên.

Sau đó, để quản lý nội dung:

  • Xác định save() chức năng để tự động kiểm tra xung đột (ví dụ có một mục nhập cho cả hai BusinessStudent liên kết với một UserProfile, hoặc không có mục).
  • Xác định các đại diện __unicode__() nếu cần.
+0

Tôi bắt đầu với việc này, nhưng sau đó tôi chuyển sang những 'mối quan hệ giữa OneToOne'' Student' và 'UserProfile' cho 'Student' và' User' vì Django quản trị wouldn' t nhận ra tên người dùng/email của các đối tượng 'UserProfile', vì các đối tượng này được lưu trữ trong' User' thay vì 'UserProfile'. Khi thêm một doanh nghiệp mới, danh sách thả xuống mối quan hệ 'OneToOne' sẽ đơn giản liệt kê' UserProfile Object' lặp đi lặp lại cho đến khi tôi thay đổi nó thành 'User', khi nó bắt đầu liệt kê tên người dùng. Tôi lo lắng về những thứ như vậy xảy ra ở các khu vực khác. Bạn có biết cách đối phó với điều đó không? – jdotjdot

+1

Có, liên kết 'UserProfile' thành' Người dùng', mà django sử dụng để đại diện cho người dùng. Để che dấu vấn đề thả xuống của bạn, hãy thêm phương thức '__unicode __()' vào 'UserProfile' để trả về' self.user.username'. Đây là tên người dùng hiển thị trong trình đơn thả xuống, tuy nhiên sẽ vẫn liên kết đến 'UserProfile'. – Rohan

+0

Cảm ơn bạn, rằng bit cuối cùng là thiên tài. Tôi sẽ để câu hỏi mở trong vài ngày để xem tôi có phản ứng gì khác, nhưng bạn đã vô cùng hữu ích. – jdotjdot

4

Tôi hy vọng tôi đã hiểu sự cố của bạn ... có thể điều này có thể hoạt động không? Bạn tạo ra một lớp CommonInfo trừu tượng mà được thừa hưởng ở vào Sub-lớp khác nhau (sinh viên và doanh nghiệp)

class CommonUser(models.Model):  
    user = models.OneToOne(User) 
    <any other common fields> 

    class Meta: 
     abstract = True 


class Student(CommonUser): 
    <whatever> 

class Business(CommonUser): 
    <whatever> 

Trong trường hợp này các mô hình sẽ được tạo trong DB với các trường lớp cơ sở trong mỗi bảng. Do đó, khi bạn làm việc với Sinh viên, bạn chạy một số điện thoại

students = Students.objects.get.all() 

để đưa tất cả sinh viên của bạn bao gồm thông tin chung.

Sau đó, cho mỗi học sinh bạn làm:

for student in students: 
    print student.user.username 

Cũng vậy với đối tượng kinh doanh.

Để có được học sinh sử dụng một người sử dụng:

student = Student.objects.get(user=id) 

Tên người dùng sẽ là duy nhất do đó khi tạo một sinh viên mới hoặc kinh doanh nó sẽ nâng cao một ngoại lệ nếu tên người dùng hiện đang được lưu.

Quên để thêm link

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