I'm trying to create some entries in the database. I am not able to input anything for the Address models. I would like to be able to add the individual fields of the shipping_address. How can I achieve this?
serializer
class UserSerializer(serializers.ModelSerializer):
"""Serializer for the users object"""
class Meta:
model = get_user_model()
fields = ('email', 'password', 'first_name', 'last_name', 'mailing_address', 'shipping_address', 'phone', 'is_active', 'is_staff', 'is_approver')
def create(self, validated_data):
"""Create a new user with encrypted password and return it"""
return get_user_model().objects.create_user(**validated_data)
models
class Address(models.Model):
first_address = models.CharField(max_length=255, blank=True, default='')
second_address = models.CharField(max_length=255, blank=True, default='')
city = models.CharField(max_length=255, blank=True, default='')
state = models.CharField(max_length=255, blank=True, default='')
zip = models.CharField(max_length=255, blank=True, default='')
class Phone(models.Model):
phone_number = PhoneField(blank=True, help_text='Contact phone number')
class ShippingAddress(models.Model):
first_address = models.CharField(max_length=255, blank=True, default='')
second_address = models.CharField(max_length=255, blank=True, default='')
city = models.CharField(max_length=255, blank=True, default='')
state = models.CharField(max_length=255, blank=True, default='')
zip = models.CharField(max_length=255, blank=True, default='')
class User(AbstractBaseUser, PermissionsMixin):
"""Custom user model that suppors using email instead of username"""
email = models.EmailField(max_length=255, unique=True)
first_name = models.CharField(max_length=255, blank=True, default='')
last_name = models.CharField(max_length=255, blank=True, default='')
password = forms.CharField(widget=forms.PasswordInput)
phone = models.ForeignKey(Phone, on_delete=models.CASCADE, null=True, blank=True)
mailing_address = models.ForeignKey(Address, on_delete=models.CASCADE, null=True, blank=True)
shipping_address = models.ForeignKey(ShippingAddress, on_delete=models.CASCADE, null=True, blank=True)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
is_approver = models.BooleanField(default=False)
objects = UserManager()
USERNAME_FIELD = 'email'
CodePudding user response:
I think you can use DRF's writable nested serializer.
Something like these (haven't tested it yet):
Add a serializer for the
Address
model:class AddressSerializer(serializers.ModelSerializer): class Meta: model = Address fields = '__all__'
And modify your current serializer for the
User
model (just like @Code-Apprentice said the comment, you can use the sameAddress
model for bothmailing_address
andshipping_address
):class UserSerializer(serializers.ModelSerializer): """Serializer for the users object""" mailing_address = AddressSerializer() shipping_address = AddressSerializer() class Meta: model = get_user_model() fields = ('email', 'password', 'first_name', 'last_name', 'mailing_address', 'shipping_address', 'phone', 'is_active', 'is_staff', 'is_approver') def create(self, validated_data): """Create a new user with encrypted password and return it""" mailing_address = Address.objects.create(**validated_data.pop('mailing_address')) shipping_address = Address.objects.create(**validated_data.pop('shipping_address')) return get_user_model().objects.create_user(mailing_address=mailing_address, shipping_address=shipping_address, **validated_data)
CodePudding user response:
How do I display fields of other models in a create view in Django?
One thing to be careful about here: Django Rest Framework provides a convenient Web interface to interact with the REST API you are building. However, this is not the only way, and probably not even the most common way, to interact with your API.
In fact, users of your app, SHOULD NOT SEE THIS WEB INTERFACE. Instead, you should build your own interface which interacts with your REST API. This gives you the flexibility to create whatever forms in HTML that you want.
For example, you can create a single form with all of the user fields along with fields for a shipping address and for a separate billing address. Then you write JavaScript in the front end to create the Address
objects with POST requests to your API. The POST request will return an id of the new address object. Then you make another POST request to create a user, with that id
and all of the other user fields.
On a side note, there is no need for a ShippingAddress
model which has the exact same fields as your Address
model. Just use Address
for all address fields:
mailing_address = models.ForeignKey(Address, on_delete=models.CASCADE, null=True, blank=True)
shipping_address = models.ForeignKey(Address, on_delete=models.CASCADE, null=True, blank=True)