2013-04-08 64 views
11

Normal Django User model ve User modele bir uzantısı olarak hizmet veren bir UserDetails modeli (User ile OneToOneField), sahip kaydedin. (Ben Django 1.5'in özelliğini denedim ve bu garip korkunç belgelere sahip bir baş ağrısı oldu, bu yüzden ben OneToOneField seçeneği ile sıkışmış)bir Django form oluşturma iki model

Bu yüzden, bir kayıt formu olacak özel bir kayıt sayfası oluşturmak için benim arayışı içinde User alanları ve UserDetails alanları, bu iki ilgili modelden otomatik olarak (tüm doğrulamaları ile) formu oluşturmanın bir yolu olup olmadığını merak ettim.

class Meta: 
    model = MyModel 

Ama iki ilgili modellerin oluşan bir form için benzer bir işlevsellik elde etmek zaten vardır: Ben bu bir modelin yapılmış bir form için çalıştığını biliyor musunuz?

+0

Evet, sadece fn kurtarış özel ile init işlevinde uzatabilirsiniz kendi modeli formunu orada yapmak olduğunu: girmek için her ModelForm durumda veri, her zamanki yöntemini kullanın. – Neal

+2

@Neal Mümkünse bir örnekle detaylandırır mısın ve cevap olarak gönderip kabul edebilir miyim? – Orca

+0

Nasıl detaylandırabileceğimi bilmiyorum ... Cevap verebileceğim tek şey yukarıdaki yorumda tam olarak nedir ... – Neal

cevap

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

iyi görünüyor, ancak sınıf Meta olmamalı: model = KullanıcıDetails ve değil model = UserDetailsForm? Ayrıca, UserDetails'ın phoneNumber adında bir alana sahip olduğunu varsayalım (\ d {10} ifadesine sahip bir regex ile), form otomatik olarak bunu yaparken (UserDetails modeliyle bağlantılı olduğu için) veya yukarıdaki kodunuzu değiştirmem gerektiğinde otomatik olarak ilgilenir mi? ? Teşekkürler – Orca

+0

üzgünüm hatam. Bunu değiştirmelisiniz çünkü gördüğüm sadece – catherine

+0

kullanıcısı için ortak alanlar koydum. İki soru daha var: 1- Özel UserDetails alanlarını (telefon gibi) eklemem gerekirse, yukarıdaki kodda bir referans yapmalıyım ya da sınıf meta, UserDetails'i işaret ettiğinden, otomatik olarak benim için bunu django yapacak mı? 2- Diğer kullanıcı alanları (şifre, kullanıcı adı) nedir? Bunları kodunuza eklemek zorunda mıyım yoksa Django bununla ilgilenir mi? – Orca

4

ModelForm'u Kullanıcı ve Kullanıcı Ayrıntıları için ayrı tutmak istiyorsanız bunu gerçekleştirmenin bir yolu, her iki formu da ön tarafa döndürmek ve her ikisinin de aynı html biçim öğesinde (yani, veri kaydedildiğinde alanlar iade edilecektir).

Bu, Kullanıcı ve KullanıcıAyrıntıları aynı ada sahip herhangi bir alana sahip değilse çalışır.

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

Kullanıcının hala kayıtlı olmadığını aklınızda bulundurun, request.user hiçbir şey (veya anonim kullanıcı) noktasına işaret etmeyin ? – Orca

+0

Bu doğru, AnonymousUser işaret eder. Daha sonra formu tekrar kullanacağın bir vakayı gösteriyordum. – legrisdev