我正面临着一个相当恼人的问题,而不是一个困难的问题。问题如下:
- 一个名为UserSerializer的给定djangorestframework ModelSerializer类使用来自模型的FileField属性的正确图像结果序列化经过身份验证的用户示例
- 当调用djangorestframework的一些通用API视图,并使用完全相同的序列化程序时,默认情况下,图像路径接收域地址
Django版本:4.2.2,Django REST Framework版本:3.14
我希望在输出中接收的内容:Django文档中提到的存储文件的路径(MEDIA_URL是'media/'),没有附加localhost域。
下图显示在RootLayout中,我收到了以/media/etc开头的正确路径。因此,我根据模式从环境变量中附加域地址,而在UsersLayout中,每个用户从某处获得我MANUAL附加域和一个自动域。
这是我的urls.py
from django.urls import include, path
from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView
from .views import *
urlpatterns = [
path('change-password/<int:pk>', UserChangePasswordView.as_view(), name='auth_change_password'), # ---- Untestable
path('languages/', LanguagesL.as_view()), # ----------------------------------------------------------- Tested
path('password_reset/', include('django_rest_passwordreset.urls', namespace='password_reset')), # -----
path('payment/barion/ipn/', PaymentBarionIPN.as_view()), # -------------------------------------------- Untestable
path('payment/barion/start/<int:pk>', UserSubscriptionCreateStart.as_view()), # ----------------------- Untestable
path('token/', TokenObtainPairView.as_view(), name='token_obtain_pair'), # ----------------------------
path('token/refresh/', TokenRefreshView.as_view(), name='token_refresh'), # ---------------------------
path('user-factor-relation-strategies/', UserFactorRelationStrategiesLC.as_view()), # ----------------- Tested
path('user-factor-relation-strategies/history/', UserFactorRelationStrategiesHistory.as_view()), # -----
path('user-factor-relations/', UserFactorRelationsLC.as_view()), # ------------------------------------ Tested
path('user-factor-relations/history/<int:pk>', UserFactorRelationsHistory.as_view()), # ---------------
path('user-factors/', UserFactorsLC.as_view()), # ----------------------------------------------------- Tested
path('user-factors/history/', UserFactorsHistory.as_view()), # -----------------------------------------
path('user-operative-actions/', UserOperativeActionsLC.as_view()), # ---------------------------------- Tested
path('user-operative-actions/history/', UserOperativeActionsHistory.as_view()), # ----------------------
path('user-swots/', UserSwotsLC.as_view()), # --------------------------------------------------------- Tested
path('user-swots/<int:pk>', UserSwotsRUD.as_view()), # ------------------------------------------------ Tested
path('users/', UsersLC.as_view()), # ------------------------------------------------------------------ Tested
path('users/<int:pk>', UsersRU.as_view()), # --------------------------------------------------------- Tested
path('users/authenticated/', AuthenticatedUser.as_view()), # ------------------------------------------ Tested
]
以上就是提到的观点
class UsersLC(generics.ListCreateAPIView):
permission_classes = [IsStaffOrWriteOnly]
serializer_class = UserSerializer
def get_queryset(self):
queryset = User.objects.all().prefetch_related('usersubscription_set')
email = self.request.query_params.get('email')
return queryset.filter(email__icontains=email) if email else queryset
class AuthenticatedUser(generics.GenericAPIView):
serializer_class = UserSerializer
def get_object(self):
return self.request.user
def get(self, request):
return Response(self.serializer_class(self.get_object()).data, status=status.HTTP_200_OK)
这是我的序列化程序类
class UserSerializer(ModelSerializer):
full_name = ReadOnlyField()
has_billing_information = ReadOnlyField()
has_valid_subscription = ReadOnlyField()
language_code = ReadOnlyField()
on_trial = ReadOnlyField()
usersubscription_set = UserSubscriptionSerializer(many=True, read_only=True)
valid_subscriptions = UserSubscriptionSerializer(many=True, read_only=True)
class Meta:
exclude = ('last_login',)
extra_kwargs = {'password': {'write_only': True}}
model = User
read_only_fields = ('is_active', 'is_staff')
def create(self, validated_data):
return User.objects.create_user(**validated_data)
最后,这是我的模型课
class User(AbstractBaseUser):
id = models.AutoField(db_column='ID', primary_key=True)
class Meta:
constraints = [models.CheckConstraint(check=models.Q(country__length__gte=2), name='User.country__min_length')]
db_table = 'Users'
accepted_eula_and_privacy_policy = models.BooleanField(db_column='AcceptedEULAandPrivacyPolicy', default=False)
address_1 = models.CharField(blank=True, db_column='Address 1', max_length=50)
address_2 = models.CharField(blank=True, db_column='Address 2', max_length=50)
city = models.CharField(blank=True, db_column='City', max_length=50)
country = models.CharField(db_column='Country (ISO 3166-1)', default='HU', max_length=2)
email = models.EmailField(db_column='Email', max_length=50, unique=True)
first_name = models.CharField(blank=True, db_column='FirstName', max_length=255)
image = models.ImageField(blank=True, db_column='Image', max_length=1000, upload_to='API_Authentication/user/image/')
is_active = models.BooleanField(db_column='Active', default=True)
is_staff = models.BooleanField(db_column='Staff', default=False)
job_title = models.CharField(blank=True, db_column='JobTitle', max_length=50)
language = models.ForeignKey(Language, db_column='LanguageID', default=2, on_delete=models.SET_DEFAULT)
last_name = models.CharField(blank=True, db_column='LastName', max_length=255)
phone_number = models.CharField(blank=True, db_column='PhoneNumber', max_length=50)
registration_date = models.DateTimeField(auto_now_add=True, db_column='RegistrationDate')
tax_number = models.CharField(blank=True, db_column='TaxNumber', max_length=13)
zip_code = models.CharField(blank=True, db_column='ZipCode', max_length=16)
objects = UserManager()
USERNAME_FIELD = 'email'
@property
def full_name(self):
return f'{self.last_name} {self.first_name}' if self.first_name and self.last_name else None
@property
def has_billing_information(self):
return (
len(self.address_1) > 0
and len(self.city) > 0
and len(self.country) > 0
and len(self.first_name) > 0
and len(self.last_name) > 0
and len(self.zip_code) > 0
)
@property
def has_valid_subscription(self):
has_valid_subscription = False
for subscription in self.usersubscription_set.all():
if subscription.validity_start < timezone.now() and subscription.validity_end > timezone.now():
has_valid_subscription = True
break
return has_valid_subscription
@property
def language_code(self):
return self.language.iso_639_1
@property
def on_trial(self):
return not self.has_valid_subscription and self.registration_date + timedelta(days=3) > timezone.now()
@property
def valid_subscriptions(self):
return self.usersubscription_set.filter(validity_end__gte=timezone.now(), validity_start__lte=timezone.now())
def __str__(self):
return self.email
如果你能给我一些提示,我会很高兴,谢谢!
1条答案
按热度按时间aamkag611#
DRF的
ImageField
派生自FileField
,其to_representation
在DRF调用序列化器时查看序列化器上下文,该上下文通常包括Djangorequest
-但如果您只是手动调用序列化器,则默认情况下上下文将为空。如果存在
request
,to_representation
将在生成的URL上调用request.build_absolute_url()
,这将预先考虑当前请求的主机、协议等。一个部分URL。似乎没有一个简单的方法来避免这种情况发生,所以如果你总是希望图像URL作为可能的相对路径,从
drf.fields.ImageField
派生,例如。并将其插入序列化器: