I want access User model's first_name, last_name and email fields from UserProfile as if they were UserProfile's own fields.
class Person(models.Model):
user = models.OneToOneField(User)
name = #ModelField which refers to user.first_name
surname = #ModelField which refers to user.last_name
email = #ModelField which refers to user.email
birth_date = models.DateField(null=True, blank=True)
#and other fields
I could use independent name, surname, email, fields but it would have caused data duplication with User fields.
upd
I want name
, surname
and email
to be of some Field
type (as birth_date) and modification of these fields to equal modification of corresponding User fields (property behavior shown below). I need this because I want these three fields to be edible in admin interface or to be prcocessed equally with "native" fields in ModelForm
for example.
upd solution. Not very fancy, but here how it worked for me:
class Person(models.Model):
user = models.OneToOneField(User)
#and also some char, text fields
@property
def name(self):
return self.user.first_name
@name.setter
def name(self, value):
self.user.first_name = value
#and by analogy surname and email properties
class PersonForm(ModelForm):
class Meta:
model = Person
exclude = ('user',)
name = forms.CharField(max_length=100, required=False)
surname = forms.CharField(max_length=100, required=False)
email = forms.EmailField(required=False)
#no make fields filled with User data on form load
def __init__(self, *args, **kwargs):
if 'instance' in kwargs:
instance = kwargs['instance']
initial = kwargs.get('initial', {})
initial['name'] = instance.name
initial['surname'] = instance.surname
initial['email'] = instance.email
kwargs['initial'] = initial
super(PersonForm, self).__init__(*args, **kwargs)
# to save form data to User model when commit
def save(self, commit=True):
instance = super(PersonForm, self).save(commit)
user = instance.user
user.first_name = self.cleaned_data['name']
user.last_name = self.cleaned_data['surname']
user.email = self.cleaned_data['email']
user.save()
return instance
class PersonAdmin(admin.ModelAdmin):
fields = ['name', 'surname', 'email', 'and_others']
form = PersonForm
admin.site.register(Person, PersonAdmin)
If want you want is to access user.first_name, user.last_name, etc... directly as attributes of Person, you can add a name, surname, etc... properties to Person model, instead of fields:
class Person(models.Model):
user = models.OneToOneField(User)
birth_date = models.DateField(null=True, blank=True)
#and other fields
@property
def name(self):
return self.user.first_name
@property
def surname(self):
return self.user.last_name
....