简体   繁体   中英

How do I display fields of other models in a create view in Django?

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'

在此处输入图像描述

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 same Address model for both mailing_address and shipping_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)

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM