SSL context override vulnerability on Django-rest serializer - django

I have HCL AppScan CodeSweep installed on VScode and it picked up an SSL context vulnerability on one of my Django serializers and I was just wondering I can go about fixing it without changing my desired functionality.
class CategoryDetailSerializer(CategoryListSerializer):
products = serializers.SerializerMethodField()
class Meta:
model = Category
fields = (
'id',
'title',
'products',
)
def get_products(self, obj):
# The source of the SSL context override
return ProductListSerializer(obj.product_set.all(), many=True, context=self.context).data
class ProductListSerializer(serializers.HyperlinkedModelSerializer):
url = serializers.HyperlinkedIdentityField(
view_name='products:product-detail-view', lookup_field='slug')
class Meta:
model = Product
fields = (
'id',
'slug',
'title',
'price',
'image',
'url',
)

Related

How to use a form with autocomplete fields in django admin update action

I am using a custom form in admin panel with two autocomplete fields among the others.
My problem is that I don't know how to use the form in update action in order the stored data to appear with the autocomplete functionality.
In my implementation in update action the values appearing without autocomplete functionality.
How can I fix that?
my form
class ModelSeoMetadatumForm(forms.ModelForm):
name = ModelChoiceField(
required=False,
queryset=MetaTag.objects.exclude(name__isnull=True).values_list('name', flat=True).distinct(),
widget=autocomplete.ModelSelect2(url='seo:name-autocomplete')
)
property = ModelChoiceField(
required=False,
queryset=MetaTag.objects.exclude(property__isnull=True).values_list('property', flat=True).distinct(),
widget=autocomplete.ModelSelect2(url='seo:property-autocomplete')
)
class Meta:
model = ModelSeoMetadatum
fields = ('name', 'content', 'property', 'content_type', 'object_id')
my admin
#admin.register(ModelSeoMetadatum)
class ModelSeoMetadatumAdmin(admin.ModelAdmin):
add_form = ModelSeoMetadatumForm
list_display = ('id', 'name', 'content', 'property', 'content_object')
fields = ('name', 'content', 'property', 'content_type', 'object_id')
def get_form(self, request, obj=None, **kwargs):
defaults = {}
if obj is None:
defaults['form'] = self.add_form
defaults.update(kwargs)
return super().get_form(request, obj, **defaults)
You should overwrite the widget and give it the admin site as parameter.
admin class:
class MyAdmin(admin.ModelAdmin):
form = MyForm
form definition:
class MyForm(forms.ModelForm):
class Meta:
widgets = {
'some_lookup_field': AutocompleteSelect(
MyModel._meta.get_field('some_lookup_field').remote_field,
admin.site,
attrs={'style': 'width: 20em'},
),
}
Note, you need to have at lease one search_filter in the admin definition of your lookup field.
Have a look here for an improved version that expands if needed link

Serializer not passing complete information to API view

I created a serializer which the "user" below is from another Serializer which i imported, now the imported serializer(PubliceProfileSerializer) works fine on its own but it does not display the content of USER when i call it my browser from this serializer. Every other item shows except the user. Please help
from rest_framework import serializers
from users.api.serializers import PublicProfileSerializer
from blog.models import Post
class PostSerializer(serializers.ModelSerializer):
user = PublicProfileSerializer(source='users.profile', read_only=True)
category = serializers.SerializerMethodField()
label = serializers.SerializerMethodField()
class Meta:
model = Post
fields = '__all__'
def get_category(self, obj):
return obj.get_category_display()
def get_label(self, obj):
return obj.get_label_display()
Add you your serializer the list of fields. Replace
fields = '__all__'
with
fields = ('id', 'user', 'category', 'label')
because:
fields = '__all__'
will only populate id, category and label from the Post model, but will not provide the nested user serializer, so it becomes:
class Meta:
model = Post
fields = ('id', 'user', 'category', 'label')
or
class PostSerializer(serializers.ModelSerializer):
user = PublicProfileSerializer(many=False,
source='users.profile',
read_only=True)
category = serializers.SerializerMethodField()
label = serializers.SerializerMethodField()
class Meta:
model = Post
fields = ('id', 'user', 'category', 'label')
def get_category(self, obj):
return obj.get_category_display()
def get_label(self, obj):
return obj.get_label_display()

Namespacing Hyperlinked Serializers in Django REST Framework

I'm currently doing the tutorial on Relationships and hyperlinked API's. However I've come across a strange problem that I can't seem to fix. My serializers.HyperlinkedIdentityField and serializers.HyperlinkedRelatedField doesnt seem to detect the namespace I'm using.
My serializers look like this
class SnippetSerializer(serializers.HyperlinkedModelSerializer):
owner = serializers.ReadOnlyField(source='owner.username')
highlight = serializers.HyperlinkedIdentityField(view_name='snippets:snippet-highlight', format='html')
class Meta:
model = Snippet
fields = ('url', 'id', 'highlight', 'owner', 'title', 'code', 'linenos', 'language', 'style')
class UserSerializer(serializers.HyperlinkedModelSerializer):
snippets = serializers.HyperlinkedRelatedField(many=True, view_name='snippets:snippet-detail', read_only=True)
class Meta:
model = User
fields = ('url', 'id', 'username', 'snippets')
Which is pretty much the same as the tutorial except I am adding view_name='snippets:snippet-detail' in the serializer field.
I am creating my namespace as suggested by the Django documentation, by adding app_name = 'snippets' above my urlpatterns.
This is the error I'm getting
ImproperlyConfigured at /snippets/
Could not resolve URL for hyperlinked relationship using view name
"snippet-detail". You may have failed to include the related model in
your API, or incorrectly configured the lookup_field attribute on
this field.
As you see, I have approached the problem the same way other people have but without resolving the issue. Anyone have an idea about what I could try next?
Solved the problem after reading some more about Hyperlinks and noticing that I should add extra_kwargs for the url field SnippetSerializer
class Meta:
model = Snippet
fields = ('url', 'id', 'highlight', 'owner', 'title', 'code', 'linenos', 'language', 'style')
extra_kwargs = {
'url': {'view_name': 'snippets:snippet-detail'},
}
And UserSerializer
class Meta:
model = User
fields = ('url', 'id', 'username', 'snippets')
extra_kwargs = {
'url': {'view_name': 'snippets:user-detail'},
}
fix this issue by modify serializer.py
we can define url, such as:
url = serializers.HyperlinkedIdentityField(view_name='snippets:user-detail', lookup_field='pk')
or define in Meta, such as
extra_kwargs = {
'url': {'view_name': 'snippet:user-detail', 'lookup_field': 'pk'},
}
all serializer.py code:
from rest_framework import serializers
from snippets.models import Snippet
from django.contrib.auth.models import User
class SnippetSerializer(serializers.HyperlinkedModelSerializer):
owner = serializers.ReadOnlyField(source='owner.username')
highlight = serializers.HyperlinkedIdentityField(lookup_field="pk", view_name='snippets:snippet-highlight', format='html')
class Meta:
model = Snippet
fields = ('url', 'id', 'highlight', 'owner', 'title', 'code', 'linenos', 'language', 'style')
extra_kwargs = {
'url': {'view_name': 'snippets:snippet-detail', 'lookup_field': 'pk'},
}
class UserSerializer(serializers.HyperlinkedModelSerializer):
snippets = serializers.HyperlinkedRelatedField(lookup_field="pk", many=True, view_name='snippets:snippet-detail', read_only=True)
url = serializers.HyperlinkedIdentityField(view_name='snippets:user-detail', lookup_field='pk')
class Meta:
model = User
fields = ('url', 'id', 'username', 'snippets')
# extra_kwargs = {
# 'url': {'view_name': 'snippet:user-detail', 'lookup_field': 'pk'},
# }
Try to pass lookup_field and lookup_url_kwarg arguments.
snippets = serializers.HyperlinkedRelatedField(many=True, view_name='snippets:snippet-detail',
lookup_field="",
lookup_url_kwarg="", read_only=True)
Refer HyperlinkedRelatedFieldDoc

Don't work cleaned_data in Django

This is my code:
class HighschoolForm(forms.ModelForm):
class Meta:
model = Highschool
fields = ['id', 'dni', 'name', 'address', 'city', 'country', 'phone', 'mobile', 'mail', 'website', 'contact', 'entrydate']
def clean_mail(self):
mail = self.cleaned_data.get('mail') #self.cleaned_data['mail']
mail_base, proveedor = mail.split('#')
dominio, extension = proveedor.split('.')
if extension == 'ptn':
raise forms.ValidationError('Does not allow Pluton mails....')
return self.cleaned_data['mail']
However when I introduced data in ModelForm in the admin view a mail with a "ptn" extension, Django doesn't refused the data and record in the database.
Which is the problem? I read de Django 2.0 documentation and I don't find the failure.
Thanks

How to position inlines in Django Admin in the list_display property?

I have two tables related Quiz and Difficulty_level:
I have created inline in admin.py like this:
class DifficultyLevelInline(admin.TabularInline):
model = DifficultyLevel
and included in QuizAdmin
To arrange the list order, I would do:
list_display = ('name', 'description', 'publication_date', 'category', 'is_active', 'is_premium')
How can I add inlines in the list_display order. I want to display The DifficultyLevelInline before category.
Unfortunately this is not possible using the default template.
If you take a look at change_form template:
https://github.com/django/django/blob/master/django/contrib/admin/templates/admin/change_form.html
You can see that inlines are always rendered after fieldsets.
One way to get around this would be to use other template:
class MyAdmin(admin.ModelAdmin):
list_display = ('name', 'description', 'publication_date', 'category', 'is_active', 'is_premium')
inlines = (DifficultyLevelInline,)
change_form_template = "my_change_form.html"
Grapelli supports it: https://django-grappelli.readthedocs.org/en/latest/customization.html#rearrange-inlines
Basically, it uses a placeholder via fieldsets and then moves them HTML via JavaScript:
https://github.com/sehmaschine/django-grappelli/blob/master/grappelli/templates/admin/change_form.html#L90-96 (search for placeholder, if the lines do not match anymore).
The same can be done by injecting custom javascript yourself (with or without using fieldsets as placeholders).
Suppose here is your inline model:
# models.py
from django.contrib.auth.models import Group
class MoreGroup(models.Model):
group = models.OneToOneField(Group, on_delete=models.CASCADE, related_name='more_group')
explain = models.CharField(verbose_name="explain_info", max_length=64, blank=True, null=True)
active = models.BooleanField(verbose_name="is_actived", default=True, blank=True, null=True)
then do this:
# admin.py
from . import models
class MoreGroupInline(admin.StackedInline):
model = models.MoreGroup
can_delete = False
verbose_name_plural = 'more_info'
class MyGroupAdmin(GroupAdmin):
list_display = ['id', 'name', 'get_inline_info']
def get_inline_info(self, obj) -> str:
mg = models.MoreGroup.objects.filter(group=obj)
if mg.count():
return mg[0].explain
else:
return '-'
get_inline_info.short_description = 'explain_info'
admin.site.register(models.Group, MyGroupAdmin)
I found a solution here: https://blog.devgenius.io/django-admin-dynamic-inline-positioning-7208596479ce
class MyAdmin(admin.ModelAdmin):
list_display = ('name', 'description', 'difficulty_level_inline', 'publication_date', 'category', 'is_active', 'is_premium')
inlines = (DifficultyLevelInline,)
def difficulty_level_inline(self, *args, **kwargs):
context = getattr(self.response, 'context_data', None) or {}
inline = context['inline_admin_formset'] = context['inline_admin_formsets'].pop(0)
return get_template(inline.opts.template).render(context, self.request)
def render_change_form(self, request, *args, **kwargs):
self.request = request
self.response = super().render_change_form(request, *args, **kwargs)
return self.response