15-vue Django restful framework to build fresh supermarket-vue and user interface information coordination

Keywords: Vue axios Python Front-end

Vue+Django REST framework

Using Python 3.6 and Django 2.0.2 (Django-rest-framework) and front-end vue to develop front-end and back-end separated mall website

The project supports Alipay payment (temporarily does not support WeChat payment), supports mobile phone SMS verification code registration, supports third party login. sentry error monitoring system is integrated.

Online demo address: http://vueshop.mtianyan.cn/
github source code address: https://github.com/mtianyan/VueDjangoFrameWorkShop

Content of this section: vue and user interface information debugging

vue and user interface information coordination

vue's Personal Center Data Details Component

src/views/member/userinfo.vue

Data loading must be in the create method.

        created () {
            this.getUserInfo();
        },

Called the getUserInfo method

 getUserInfo () { //Request user information
              getUserDetail().then((response)=> {
                    this.userInfo = response.data;
                }).catch(function (error) {
                    console.log(error);
                });
            },

Call the getUserDeatil interface, and then fill in the data of the response data as Userinfo.

//Getting User Information
export const getUserDetail = () => { return axios.get(`${host}/users/1/`) }

Change host to localhost

User Personal Information Modification

Configure update mixins for UserViewset

This carries the operation of updating and partial updating.

It accepts put and patch requests. Put is actually an update operation, and patch is a partial update.

class UserViewset(CreateModelMixin, mixins.UpdateModelMixin, mixins.RetrieveModelMixin, viewsets.GenericViewSet):

Logic in vue

<button class="btn_blue_1" style="border:none;" @click="confirmModify">Confirm revision</button>

Verify that the modification calls the confirmModify method.

            confirmModify () { // Confirm revision
                updateUserInfo(this.userInfo).then((response)=> {
                    alert('Modified success');
                }).catch(function (error) {
                    console.log(error);
                });
            }

This calls the interface updateUserInfo

//Modify user information
export const updateUserInfo = params => { return axios.patch(`${host}/users/1/`, params) }

Change host to localhost

The user username has been updated to be Chinese random code. As well as modifying the user's name, identity authentication is invalid

User Collection Function

Our previous List modelmixin in UserFavViewSet has returned the id of goods and the id of this collection relationship. But what we need is information about goods, so in Serilizer

Add a Serializers

class UserFavDetailSerializer(serializers.ModelSerializer):

    # Get the product information through goods_id. Nested Serilizer is needed
    goods = GoodsSerializer()
    class Meta:
        model = UserFav
        fields = ("goods", "id")

Collection submission only needs to pass goods'id over, and user favdetail wants to get goods' details when it gets them.

Dynamic Serializer.

    # Setting up dynamic Serializer
    def get_serializer_class(self):
        if self.action == "list":
            return UserFavDetailSerializer
        elif self.action == "create":
            return UserFavSerializer

        return UserFavSerializer

You can also write a separate Serilizer that returns only the brief information in the collection.

src/views/member/collection.vue:

Call getCollection when create

        created () {
            this.getCollection();
        },

The getcollection method takes the data returned by the getAllFavs interface and fills it in

            getCollection () { //Get a collection list
              getAllFavs().then((response)=> {
                    this.collections = response.data;
                }).catch(function (error) {
                    console.log(error);
                });
            },

Modify getallfav as the local interface

export const getAllFavs = () => { return axios.get(`${local_host}/userfavs/`) }

Delete operation:

<a class="f6" @click="deletePro(index, item.goods.id)">delete</a>

Delete operation calls deletePro and passes in index index and goods.id as parameters

            deletePro (index, id) { //Delete Collected Goods
                alert('Are you sure you want to delete the selected item from your collection?');
                delFav(id).then((response)=> {
                    this.collections.splice(index,1);
                    alert('Deleted goods');
                }).catch(function (error) {
                    console.log(error);
                });
            }

splice deletes the data in vue, making the front page one less.

delfav deletes back-end database data.

//Cancel collection
export const delFav = goodsId => { return axios.delete(`${local_host}/userfavs/`+goodsId+'/') }

User Message Function

Delete, get messages, add user messages. You can upload files in your message.

Background interface viewset and supporting Serilizer

user_operation/serializers.py:

class LeavingMessageSerializer(serializers.ModelSerializer):
    user = serializers.HiddenField(
        default=serializers.CurrentUserDefault()
    )
    add_time = serializers.DateTimeField(read_only=True, format='%Y-%m-%d %H:%M')
    class Meta:
        model = UserLeavingMessage
        fields = ("user", "message_type", "subject", "message", "file", "id" ,"add_time")

The user gets the current user directly, and the add_time settings are readable and formatted.

class LeavingMessageViewset(mixins.ListModelMixin, mixins.DestroyModelMixin, mixins.CreateModelMixin,
                            viewsets.GenericViewSet):
    """
    list:
        //Getting User Messages
    create:
        //Add message
    delete:
        //Delete message function
    """

    permission_classes = (IsAuthenticated, IsOwnerOrReadOnly)
    authentication_classes = (JSONWebTokenAuthentication, SessionAuthentication)
    serializer_class = LeavingMessageSerializer

    # You can only see your message
    def get_queryset(self):
        return UserLeavingMessage.objects.filter(user=self.request.user)

Return only the message of the current user

Configure a matching url

Implementation code:

# Configure the url for user messages
router.register(r'messages', LeavingMessageViewset, base_name="messages")

When we delete, we need the id returned by the server. Front-end and back-end separated system, the server returns the full address can be directly viewed by the front-end.

addtime should only be returned without submitting. Fill in automatically by the current time obtained.

vue source interface

//Get messages
export const getMessages = () => {return axios.get(`${host}/messages/`)}

//Add message
export const addMessage = params => {return axios.post(`${host}/messages/`, params, {headers:{ 'Content-Type': 'multipart/form-data' }})}

//Delete message
export const delMessages = messageId => {return axios.delete(`${host}/messages/`+messageId+'/')}

Change all host s to localhost

How to replace T in time with a space symbol? Add a format for add_time

How does the data filling mapping work? The component is src/views/member/message.vue

        created () {
            this.getMessage();
        },

Call getmessage() before component creation

            getMessage () { //Get messages
              getMessages().then((response)=> {
                    console.log(response.data);
                    this.messageAll = response.data;
                }).catch(function (error) {
                    console.log(error);
                });
            },
//Get messages
export const getMessages = () => {return axios.get(`${local_host}/messages/`)}

Get all messages and assign values to messageAll for filling

mark

The if conditional mapping here should be consistent with our model

Deletion calls deleteMessage

<a @click="deleteMessage(index, item.id)">delete</a>

            deleteMessage (index, id) { // Delete message
                delMessages(id).then((response)=> {
                  alert("Delete successful")
                  this.messageAll.splice(index,1);
                }).catch(function (error) {
                    console.log(error);
                });
            },
//Delete message
export const delMessages = messageId => {return axios.delete(`${local_host}/messages/`+messageId+'/')}

Upload files (work done at the front end)

            submitMessage () { //Submit message
                const formData = new FormData();
                formData.append('file',this.file);
                formData.append('subject',this.subject);
                formData.append('message',this.message);
                formData.append('message_type',this.message_type);
                addMessage(formData).then((response)=> {
                    this.getMessage();

                }).catch(function (error) {
                    console.log(error);
                });
            },

formdata in es is used. file append in.

//Add message
export const addMessage = params => {return axios.post(`${local_host}/messages/`, params, {headers:{ 'Content-Type': 'multipart/form-data' }})}

When addmessage is passed in, the head indicates its type multipart/form-data.

How does drf parse and save files in our database?

parse section of the document.

mark

You can see that drf provides us with a variety of parse s

MultiPartParser

file in the model we can set upload_to

    file = models.FileField(upload_to="message/images/", verbose_name="Uploaded Documents", help_text="Uploaded Documents")

Development of Page Interface for User Receiving Address List

The delivery address is also placed in user_operation. Get all the receiving addresses and modify one of them.
Delete a receiving address.

Need lists, additions, updates, deletions: inheritance additions, deletions, modifications, mixin s, but if needed, then there is a viewset that has already helped us.

class ModelViewSet(mixins.CreateModelMixin,
                   mixins.RetrieveModelMixin,
                   mixins.UpdateModelMixin,
                   mixins.DestroyModelMixin,
                   mixins.ListModelMixin,
                   GenericViewSet):

We just need to inherit from the Model ViewSet.

Add a matching Serilizer.

class AddressSerializer(serializers.ModelSerializer):
    user = serializers.HiddenField(
        default=serializers.CurrentUserDefault()
    )
    add_time = serializers.DateTimeField(read_only=True, format='%Y-%m-%d %H:%M')

    class Meta:
        model = UserAddress
        fields = ("id", "user", "province", "city", "district", "address", "signer_name", "add_time", "signer_mobile")

The user is the current user.

When filling back an address, if it is an address to fill back all its provinces and municipalities, it will be separated, which is more troublesome. So we set three fields for storage. Provincial and Urban Areas

Configuration in viewset

class AddressViewset(viewsets.ModelViewSet):
    """
    Receiving Address Management
    list:
        Get the shipping address
    create:
        Add Receiving Address
    update:
        Update Receiving Address
    delete:
        Delete the Receiving Address
    """
    permission_classes = (IsAuthenticated, IsOwnerOrReadOnly)
    authentication_classes = (JSONWebTokenAuthentication, SessionAuthentication)
    serializer_class = AddressSerializer

    def get_queryset(self):
        return UserAddress.objects.filter(user=self.request.user)

Configure in url:

# Receiving address
router.register(r'address', , base_name="address")
mark

Optional job: Validation of additional fields. Such as mobile phone number.

vue and receiving address interface debugging

Interface in vue about receiving address

//Add Receiving Address
export const addAddress = params => {return axios.post(`${host}/address/`, params)}

//Delete the Receiving Address
export const delAddress = addressId => {return axios.delete(`${host}/address/`+addressId+'/')}

//Modification of Receiving Address
export const updateAddress = (addressId, params) => {return axios.patch(`${host}/address/`+addressId+'/', params)}

//Get the shipping address
export const getAddress = () => {return axios.get(`${host}/address/`)}

Change all four host s to localhost

src/views/member/receive.vue: This is the component of our receiving address.

When components are created

        created () {
            this.getReceiveInfo();
        },

getreceiveInfo() calls the getaddress interface

getReceiveInfo() { //Getting recipient information
                getAddress().then((response)=> {
                    console.log(response.data);
                    this.receiveInfoArr = response.data;

                }).catch(function (error) {
                    console.log(error);
                });

            },

ReciveInfoArr traverses the data.

        <v-distpicker :province="newInfo.province" :city="newInfo.city" :area="newInfo.district" @province="getProvince" @city="getCity" @area="getArea"></v-distpicker>

Known bug s, set up Chang'an District of Xi'an City, the district does not display.

Posted by OmegaB on Wed, 19 Dec 2018 23:15:05 -0800