I'm trying to use the clean method of a model in my project, but I get the error:
RelatedObjectDoesNotExist at /profile/social/add
ProfileSocialMedia has no profile.
I've tried a lot of different things, but I still can't figure out what I'm doing wrong
What I want to do is, this class is associated with a profile and also with a social profile, where the identification field will be a number or a link to a profile on a social network, before saving the data I want to do some checks
the check that is generating the problem is apparently the clean_social_media def in print(profile)
If I delete this check the error occurs in other cleans, which makes me think that perhaps the profile is not being passed correctly.
In this check, basically I want to block the creation of an object from the ProfileSocialMedia model if the profile I am creating already has 6 or more social networks created.
Everything works, it saves correctly, but when it reaches the limit (6) it generates the error Precisely for this reason I have more doubts, because when it reaches the limit the error is generated?
Below is my code
class ProfileSocialMedia(models.Model):
profile = models.ForeignKey(Profile, related_name="medias", `enter code here`on_delete=models.CASCADE)
social_media = models.ForeignKey(SocialMedia, on_delete=models.CASCADE, blank=False)
identification = models.CharField("Identification", max_length=3000)
def __str__(self):
return f"Profile Owner: {self.profile.user.first_name} / Social Media: {self.social_media.name}"
class Meta:
verbose_name = 'Profile Social Media'
verbose_name_plural = 'Profile Social Medias'
def clean_social_media(self):
if self.social_media is None:
raise ValidationError("Por favor, selecione uma rede social")
print(self.profile)
def clean_identification(self):
if self.social_media.is_link == False:
validate_number(self.identification)
else:
validate_url(self.identification)
def clean_socials(self):
limit = 6
socials = self.profile.medias.all()
if socials.count() >= limit:
raise ValidationError("Você atingiu o limite(6) de redes socias que podem ser adicionadas, altere ou exclua uma rede social existente.")
def clean(self):
self.clean_identification()
self.clean_social_media()
self.clean_socials()
def save(self, *args, **kwargs):
if self.social_media.is_link:
if not re.match(r'^https?://', self.identification):
self.identification = f'https://{self.identification}'
self.full_clean()
super().save(*args, **kwargs)
class AddSocialMediaForm(forms.ModelForm):
social_media = forms.ModelChoiceField(required=True, label='Escolha uma rede social', empty_label=None, queryset=SocialMedia.objects.all(), widget=forms.Select(attrs={'class':'update-form'}))
identification = forms.CharField(required=True, label='Identificação da rede social', widget=forms.TextInput(attrs={'class':'update-form'}), help_text='Insira o número para adicionar o whatsapp no formato cód país + ddd + número, ex: (+55)24981094563 ou link do perfil para todas as outras redes.')
def __init__(self, **kwargs):
self.profile = kwargs.pop('profile', None)
super(AddSocialMediaForm, self).__init__(**kwargs)
class Meta:
model = ProfileSocialMedia
fields = ('social_media', 'identification')
class AddSocialMediaView(TemplateView):
template_name = 'add_social_media.html'
def post(self, request):
profile_user = get_object_or_404(Profile, user=request.user)
form = AddSocialMediaForm(data=request.POST or None, profile=profile_user)
message_save_data_successfully = "Os seus dados foram atualizados."
message_auth_error = 'Você precisa estar autenticado para acessar esta página, portanto, será redirecionado para a página inicial após 5 segundos.'
if request.user.is_authenticated:
if form.is_valid():
social_media = form.save(commit=False)
social_media.profile = profile_user
social_media.save()
else:
return render(request, self.template_name, {'form': form})
else:
messages.error(request, (message_auth_error), extra_tags='message_auth_error')
return render(request, self.template_name, {'message_auth_error':message_auth_error})
messages.success(request, (message_save_data_successfully), extra_tags='message_save_data_successfully')
return render(request, self.template_name, {'message_save_data_successfully':message_save_data_successfully})
def get(self, request):
profile_user = Profile.objects.get(user__id=request.user.id)
form = AddSocialMediaForm(data=request.GET or None, profile=profile_user)
message_auth_error = 'Você precisa estar autenticado para acessar esta página, portanto, será redirecionado para a página inicial após 5 segundos.'
if request.user.is_authenticated:
return render(request, self.template_name, {'form':form})
else:
messages.error(request, (message_auth_error), extra_tags='message_auth_error')
return render(request, self.template_name, {'message_auth_error':message_auth_error})
I want the clean method to work correctly, I'm implementing it in the model because I want it to work regardless of where I'm sending the data