2013-04-08 11 views
11

मैं नियमित रूप से Django User मॉडल और एक UserDetails मॉडल (User साथ OneToOneField) है, जो User मॉडल के लिए एक विस्तार के रूप में कार्य करता है है। (मैंने Django 1.5 की सुविधा की कोशिश की और यह अजीब भयानक दस्तावेज़ीकरण के साथ एक सिरदर्द था, इसलिए मैं OneToOneField विकल्प के साथ अटक गया)एक Django फार्म बनाना बचाने के लिए दो मॉडल

तो, एक कस्टम पंजीकरण पृष्ठ बनाने के लिए मेरी तलाश में, जिसमें एक पंजीकरण फॉर्म होगा User फ़ील्ड और UserDetails फ़ील्ड, मुझे आश्चर्य हुआ कि क्या इन दो संबंधित मॉडलों में से फ़ॉर्म को स्वचालित रूप से (इसके सभी सत्यापनों के साथ) उत्पन्न करने का कोई तरीका था।

class Meta: 
    model = MyModel 

लेकिन एक फार्म दो संबंधित मॉडल के शामिल के लिए एक इसी तरह की सुविधा पाने के लिए वहाँ वैसे भी है: मैं इस एक रूप एक मॉडल से बना लिए काम करता है पता है?

+0

हाँ वहाँ है, बस अपना स्वयं का मॉडल फार्म का है कि आप fn बचाने के लिए एक कस्टम के साथ init समारोह में विस्तार कर सकते हैं करते हैं: इनपुट करने के लिए प्रत्येक ModelForm उदाहरण में डेटा, आप हमेशा की विधि का उपयोग करें। – Neal

+2

@Neal क्या आप कृपया उस पर विस्तृत जानकारी दे सकते हैं, यदि संभव हो तो उदाहरण के साथ, और इसे उत्तर के रूप में पोस्ट करें ताकि मैं इसे स्वीकार कर सकूं? – Orca

+0

मुझे नहीं पता कि मैं कैसे विस्तार कर सकता हूं ... एकमात्र चीज जो मैं एक जवाब में डालूंगा वह बिल्कुल मेरी टिप्पणी में क्या है ... – Neal

उत्तर

13
from django.forms.models import model_to_dict, fields_for_model 


class UserDetailsForm(ModelForm): 
    def __init__(self, instance=None, *args, **kwargs): 
     _fields = ('first_name', 'last_name', 'email',) 
     _initial = model_to_dict(instance.user, _fields) if instance is not None else {} 
     super(UserDetailsForm, self).__init__(initial=_initial, instance=instance, *args, **kwargs) 
     self.fields.update(fields_for_model(User, _fields)) 

    class Meta: 
     model = UserDetails 
     exclude = ('user',) 

    def save(self, *args, **kwargs): 
     u = self.instance.user 
     u.first_name = self.cleaned_data['first_name'] 
     u.last_name = self.cleaned_data['last_name'] 
     u.email = self.cleaned_data['email'] 
     u.save() 
     profile = super(UserDetailsForm, self).save(*args,**kwargs) 
     return profile 
+0

अच्छा दिखता है, लेकिन क्लास मेटा नहीं होना चाहिए: मॉडल = उपयोगकर्ता विवरण और मॉडल = उपयोगकर्ता डेटाफॉर्म नहीं? साथ ही, मान लीजिए कि उपयोगकर्ता डिस्प्ले में फ़ोन नंबर नामक एक फ़ील्ड है (\ d {10} के लिए रेगेक्स के साथ) फॉर्म स्वचालित रूप से उस पर ध्यान देता है जब आप इसे डालते हैं (क्योंकि यह उपयोगकर्ता डिस्प्ले मॉडल से जुड़ा हुआ है) या क्या मुझे उपरोक्त कोड को संशोधित करने की आवश्यकता है ? धन्यवाद – Orca

+0

मेरी गलती क्षमा करें। आपको इसे संशोधित करना होगा क्योंकि मैं केवल उपयोगकर्ता – catherine

+0

के लिए सामान्य फ़ील्ड डालता हूं। दो और प्रश्न: 1- यदि मुझे कस्टम उपयोगकर्ता विवरण फ़ील्ड (जैसे फ़ोन) जोड़ना है, तो मुझे उपरोक्त कोड में इसका संदर्भ कहां देना चाहिए, या django स्वचालित रूप से मेरे लिए ऐसा करेगा क्योंकि क्लास मेटा अब उपयोगकर्ता विवरण को इंगित करता है? 2- अन्य उपयोगकर्ता फ़ील्ड (पासवर्ड, उपयोगकर्ता नाम) के बारे में क्या? क्या मुझे उन्हें अपने कोड में जोड़ना है या Django इसका ख्याल रखता है? – Orca

4

एक तरीका यह है कि आप इसे पूरा कर सकते हैं, यदि आप उपयोगकर्ता के लिए मॉडलफॉर्म रखना चाहते हैं और उपयोगकर्ता विवरण अलग-अलग दोनों रूपों को सामने के अंत में वापस करना होगा, और सुनिश्चित करें कि वे दोनों एक ही HTML फॉर्म तत्व (यानी सभी डेटा पोस्ट होने पर फ़ील्ड वापस कर दिए जाएंगे)।

यह काम करता है यदि उपयोगकर्ता और उपयोगकर्ता के विवरण में एक ही नाम के साथ कोई फ़ील्ड नहीं है।

form_user = UserForm(request.POST, instance=request.user) 
    form_user_details = UserDetailsForm(request.POST, instance=request.user.userdetails) 
+0

ध्यान में रखते हुए कि उपयोगकर्ता अभी भी पंजीकृत नहीं है, अनुरोध नहीं करेगा। उपयोगकर्ता कुछ भी नहीं (या अज्ञात उपयोगकर्ता) ? – Orca

+0

यह सही है, यह अनामित उपयोगकर्ता को इंगित करेगा। मैं सिर्फ एक मामला दिखा रहा था जहां आप बाद में फॉर्म का फिर से उपयोग करेंगे। – legrisdev

संबंधित मुद्दे