编辑:我已经编辑了我的问题,包括我的代码:
我正在DRF中构建一个Web API。还有第三方API,其响应返回ip_address
、latitude
、longitude
等字段。我有一个用户模型(它基本上是从AbstractBaseUser
继承的),它包含像email
、username
、first_name
和last_name
这样的字段。创建这个用户模型的示例是可行的。
但是我想做的是保存来自这个第三方API的响应,作为一个名为Artist的模型的示例,每当这个用户模型的示例被保存时,它都有一个带有用户模型的OneToOneField。我该怎么做?
注意:我让Djoser,一个处理身份验证的第三方库,负责我的用户模型上的身份验证端点。因此,到目前为止,这个项目还没有涉及到任何意见。
以下是我目前为止的代码:
import uuid
import requests
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin
from django.db import models
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from .managers import CustomUserManager
class UserGeoData(models.Model):
ip_address = models.GenericIPAddressField(default="0.0.0.0")
city = models.CharField(max_length=50)
region_iso_code = models.CharField(max_length=5)
country_code = models.CharField(max_length=5)
longitude = models.DecimalField(max_digits=9, decimal_places=6)
latitude = models.DecimalField(max_digits=9, decimal_places=6)
class User(AbstractBaseUser, PermissionsMixin):
pkid = models.BigAutoField(primary_key=True, editable=False)
id = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)
username = models.CharField(verbose_name=_("Username"), max_length=255, unique=True)
first_name = models.CharField(verbose_name=_("First Name"), max_length=50)
last_name = models.CharField(verbose_name=_("Last Name"), max_length=50)
email = models.EmailField(verbose_name=_("Email Address"), unique=True)
usergeo = models.OneToOneField(UserGeoData, on_delete=models.CASCADE, null=False)
is_staff = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
date_joined = models.DateTimeField(default=timezone.now)
USERNAME_FIELD = "email"
REQUIRED_FIELDS = ["username", "first_name", "last_name"]
objects = CustomUserManager()
class Meta:
verbose_name = _("User")
verbose_name_plural = _("Users")
def __str__(self):
return self.username
@property
def get_full_name(self):
return f"{self.first_name} {self.last_name}"
def get_short_name(self):
return self.username
def save(self, *args, **kwargs):
url = "https://ipgeolocation.abstractapi.com/v1/?api_key=d77f75a5593e4073a6eb1bef9c35e929"
response = requests.get(url)
data = response.json()
obj, created = UserGeoData.objects.get_or_create(
ip_address=data["ip_address"],
defaults={
"city": data["city"],
"region_iso_code": data["region_iso_code"],
"country_code": data["country_code"],
"longitude": data["longitude"],
"latitude": data["latitude"],
},
)
self.ship = obj
return super().save()
# class Holiday(models.Model):
# user = models.OneToOneField(User, on_delete=models.CASCADE)
# holiday_name = models.CharField(max_length=120)
# holiday_type = models.CharField(max_length=120)
# date = models.DateTimeField(auto_now=True)
# class Security(models.Model):
# usergeodata = models.OneToOneField(UserGeoData, on_delete=models.CASCADE)
# is_vpn = models.BooleanField(default=False)
这是我的用户管理器:
from django.contrib.auth.base_user import BaseUserManager
from django.core.exceptions import ValidationError
from django.core.validators import validate_email
from django.utils.translation import gettext_lazy as _
class CustomUserManager(BaseUserManager):
def email_validator(self, email):
try:
validate_email(email)
except ValidationError:
raise ValueError(_("You must provide a valid email address"))
def create_user(
self, username, first_name, last_name, email, password, **extra_fields
):
if not username:
raise ValueError(_("Users must submit a username"))
if not first_name:
raise ValueError(_("Users must submit a first name"))
if not last_name:
raise ValueError(_("Users must submit a last name"))
if email:
email = self.normalize_email(email)
self.email_validator(email)
else:
raise ValueError(_("Base User Account: An email address is required"))
user = self.model(
username=username,
first_name=first_name,
last_name=last_name,
email=email,
**extra_fields
)
user.set_password(password)
extra_fields.setdefault("is_staff", False)
extra_fields.setdefault("is_superuser", False)
user.save(using=self._db)
return user
def create_superuser(
self, username, first_name, last_name, email, password, **extra_fields
):
extra_fields.setdefault("is_staff", True)
extra_fields.setdefault("is_superuser", True)
extra_fields.setdefault("is_active", True)
if extra_fields.get("is_staff") is not True:
raise ValueError(_("Superusers must have is_staff=True"))
if extra_fields.get("is_superuser") is not True:
raise ValueError(_("Superusers must have is_superuser=True"))
if not password:
raise ValueError(_("Superusers must have a password"))
if email:
email = self.normalize_email(email)
self.email_validator(email)
else:
raise ValueError(_("Admin Account: An email address is required"))
user = self.create_user(
username, first_name, last_name, email, password, **extra_fields
)
user.save(using=self._db)
return user
1条答案
按热度按时间iyzzxitl1#
基本上,通过覆盖您的自定义用户
save
方法。下面是一个使用SWAPI为用户分配Ship
的简单示例:models.py
为了简单起见,使用了
AbstractUser
。P.S.你想要Python requests