models.py写一个地址信息类
class AddressInfo(models.Model):
# 需要写外键,对应用户
user = models.ForeignKey(Users, on_delete=models.CASCADE, related_name='address', verbose_name='用户')
receiver = models.CharField(max_length=20, verbose_name='收货人')
# 导不是当前页面的外键
province = models.ForeignKey('areas.Areas', on_delete=models.PROTECT, verbose_name='省份', related_name='province_address')
city = models.ForeignKey('areas.Areas', on_delete=models.PROTECT, verbose_name='省份', related_name='city_address')
district = models.ForeignKey('areas.Areas', on_delete=models.PROTECT, verbose_name='省份', related_name='district_address')
detail_place = models.CharField(max_length=50, verbose_name='详细地址')
postcode = models.CharField(max_length=6, verbose_name='邮编')
phone = models.CharField(max_length=11, verbose_name='手机')
# 设置是否为默认地址
# 逻辑删除
is_delete = models.BooleanField(default=False, verbose_name='逻辑删除')
class Meta:
db_table = 'sh_user_address'
verbose_name_plural = '地址管理'
可以有两种方法,一是在收货地址这个模型类中多加一个字段,证明是默认收货地址,但是这个方法在设置默认地址和取消默认地址的时候,会很麻烦,取消默认地址的时候,需要先查哪个是默认地址,然后取消那个标记,然后再设置另外一个标记,这样多增加了数据库的操作。
第二种方法是在用户表中多加一个字段,外键关联到要设置默认地址的那条记录上,这里采用这种方法
为User模型类添加默认地址
class User(AbstractUser):
...
default_address = models.ForeignKey('Address', related_name='users', null=True, blank=True, on_delete=models.SET_NULL, verbose_name='默认地址')
...
这次暂时没写这个默认地址,下次补齐
from .views import *
from rest_framework.routers import DefaultRouter
# 路由器
router = DefaultRouter()
router.register(r'^addressinfo', AddressInfoView, base_name='addressinfo')
urlpatterns = []
urlpatterns += router.urls
class AddressInfoView(ModelViewSet):
# 地址增删改查
serializer_class = AddressSerCLass
# 权限
permission_classes = (IsAuthenticated, )
def get_queryset(self):
print('inner')
print(self.request.user.address.filter(is_delete=False))
return self.request.user.address.filter(is_delete=False)
def list(self, request, *args, **kwargs):
query_set = self.get_queryset()
ser = self.get_serializer(query_set, many=True)
return Response({
'address': ser.data
})
def create(self, request, *args, **kwargs):
# 检查用户地址数据的数量不能超过上限
# 获取用户地址的数量
count = request.user.address.count()
if count >= 10:
return Response({'errmsg': '不能超过10条'})
return super().create(request, *args, **kwargs)
def destroy(self, request, *args, **kwargs):
# 删除把逻辑删除置为真即可
add_obj = self.get_object()
add_obj.is_delete = True
add_obj.save()
return Response('删除成功')
因为省市区三个是外键所以自动会变成_id后缀
class AddressSerCLass(serializers.ModelSerializer):
province_id = serializers.IntegerField(required=True)
city_id = serializers.IntegerField(required=True)
district_id = serializers.IntegerField(required=True)
province = serializers.StringRelatedField(read_only=False)
city = serializers.StringRelatedField(read_only=False)
district = serializers.StringRelatedField(read_only=False)
class Meta:
model = AddressInfo
exclude = ('user', 'is_delete')
def create(self, validated_data):
print('#####################')
print(self.context['request'].user) # 取得user
validated_data['user'] = self.context['request'].user
return super().create(validated_data)
*注意,get_serializer(self, args, kwargs)方法在提供序列化器对象的时候,会向序列化器对象的context属性补充三个数据:request、format、view,这三个数据对象可以在定义序列化器时使用。
# 判断用户是否在60s内使用同一个手机号码获取短信,mobile为手机号。通过context来获取当前类视图对象,通过kwargs来获取mobile。
mobile = self.context['view'].kwargs['mobile']
send_flag = redis_conn.get('send_flag_%s' % mobile)
if send_flag:
raise serializers.ValidationError('频繁发送短信')
也可以用postman模拟
/**
* Created by python on 19-6-24.
*/
// 这个js是写展示省市区
var token = localStorage.token;
function get_son_areaid(select_name, father_id) {
// 显示下一级区域的方法
$.ajax({
type: 'GET',
url: 'http://127.0.0.1:8000/areas/info/' + father_id,
success: function(data) {
$(select_name).empty();
console.log(data);
var arr=data.addinfo;
$.each(arr, function(index, value) {
$(select_name).append(" value.id + '>' + value.name + '')
});
if (select_name == "#select_cities"){
console.log('xiangtong', arr[0].id);
get_son_areaid('#select_district', arr[0].id)
}
},
error: function() {
alert('读取失败')
}
})
}
$(function () {
// 显示省份
$.ajax({
type: 'GET',
url: 'http://127.0.0.1:8000/areas/info/',
success: function(data) {
console.log(data);
$("#select_provinces").empty();
$.each(data, function(index, value) {
// $("#select_provinces").append("")
//为Select追加一个Option(下拉项)
$("#select_provinces").append(" value.id + '>' + value.name + '');
})
},
error: function() {
alert('读取省份失败')
}
});
// 选择省份显示市
$('#select_provinces').change(function() {
var check_val= $(this).val();
get_son_areaid("#select_cities", check_val);
});
// 选择市显示区
$('#select_cities').change(function() {
var check_val= $(this).val();
get_son_areaid("#select_district",check_val)
});
});
/**
* Created by python on 19 - 6 - 21.
*/
var token = localStorage.token;
$(function() {
// 展示所有地址
$.ajax({
url: 'http://127.0.0.1:8000/users/addressinfo/',
headers: {
'Authorization': 'JWT ' + token
},
type: 'GET',
dataType:'json',
contentType: 'application/json',
success:function (data) {
console.log(data);
// 张小泉 江苏南京雨花台区 大件路4号软件大厦B栋102室 210000 12343323221 个人 修改 | 删除
$('#show_address').html('');
$.each(data, function (add, arr) {
for (var i=0; i<arr.length;i++){
add_obj = arr[i];
add_id = add_obj['id'];
$('#show_address').append(""+add_obj['receiver']+" "+add_obj['province']+add_obj['city']+add_obj['district']+" "+add_obj['detail_place']+" "+add_obj['postcode']+" "+add_obj['phone']+" 个人 修改 | 删除 ");
}
})
},
error:function (data) {
alert('展示地址失败');
console.log(data)
}
})
});
// 保存地址,拼接内容,用户名,地址,手机号,邮编,是否默认
function click_save_address() {
var receiver = $('#receiver').val();
var province = $('#select_provinces').val();
var city = $('#select_cities').val();
var district = $('#select_district').val();
var detail_place = $('#detail_place').val();
var postcode = $('#postcode').val();
var phone = $('#phone').val();
console.log(token);
var send_data = {
'receiver': receiver,
'province_id': province,
'city_id': city,
'district_id': district,
'detail_place': detail_place,
'postcode': postcode,
'phone': phone
};
send_data = JSON.stringify(send_data);
$.ajax({
url: 'http://127.0.0.1:8000/users/addressinfo/',
headers: {
'Authorization': 'JWT ' + token
},
type: 'POST',
data: send_data,
dataType:'json',
contentType: 'application/json',
success:function (data) {
console.log(data)
},
error:function (data) {
alert('保存地址失败');
console.log(data)
}
})
}
// 删除一个地址
function delete_address(add_id) {
alert(add_id);
$.ajax({
url: 'http://127.0.0.1:8000/users/addressinfo/' +add_id +'/',
headers: {
'Authorization': 'JWT ' + token
},
type: 'DELETE',
dataType:'json',
contentType: 'application/json',
success:function (data) {
console.log(data)
},
error:function (data) {
alert('删除地址失败');
console.log(data)
}
})
}
重点是a标签跳转网页时带上id参数:
<a href='user_updateadd.html?id="+add_id+"'>修改</a>
然后是在修改网页如何用Jq获取到这个参数
// 取得当前的id值
function GetRequest() {
var url = location.search; //获取url中"?"符后的字串
var theRequest = new Object();
if (url.indexOf("?") != -1) {
var str = url.substr(1);
strs = str.split("&");
for (var i = 0; i < strs.length; i++) {
theRequest[strs[i].split("=")[0]] = decodeURIComponent(strs[i].split("=")[1]);
}
}
return theRequest;
}
var a=GetRequest();
console.log("id:"+a['id']);
最后发送一个请求类型为PUT的ajax请求即可,带上修改的数据,验证用户信息请求头