I have a model field
account_handler = models.ForeignKey(User, blank=True, null=True, related_name='handling_leads', on_delete=models.SET_NULL)
Currently I'm doing something like this
def get_queryset(self):
user_id = User.objects.all()
queryset = User.objects.filter(handling_leads__account_handler=user_id).distinct()
return queryset
and I've got some results for testing purposes. Now the question is, how can I properly use this field and return a user_id? I have tried something like this
User.objects.filter(handling_leads__account_handler=self.request.user.id).distinct()
with out User.objects.all() but that was just returning an empty queryset. I'm trying to filter this so I can populate a table with user__first_name and user__last_name, I need user_id so I can redirect them to their individual page.
controler for the datatable:
app = angular.module 'statistics'
app.controller 'SalesCommissionsListCtrl', ['$scope', '$compile',
($scope, $compile) ->
$scope.init = ()->
fetchCommissionsList()
fetchCommissionsList = ()->
$('#commissionsSalesList').DataTable({
createdRow: (row, data, index) ->
$compile(row)($scope)
sDom: 'lftip',
processing: true,
serverSide:true,
searchDelay: 1000,
orderMulti: false,
pageLength: 10,
ajax: {
url: '/api/statistics/commissions/list/',
data: (data)->
data.limit = data.length;
data.offset = data.start;
data.search = data.search['value'];
if (data.order[0]['dir'] == 'asc')
data.ordering = data.columns[data.order[0]['column']].name;
else
data.ordering = '-' + data.columns[data.order[0]['column']].name;
return 0
dataFilter: (data) ->
json = jQuery.parseJSON(data);
json.recordsTotal = json.count;
json.recordsFiltered = json.count;
json.data = json.results;
return JSON.stringify(json);
}
columns: [
{
data: "username",
name: "username__first_name, username__last_name",
render: (data, type, row, meta)->
return '' + data + '';
}
]
})
]
my ModelViewSet:
from django.contrib.auth.models import User
from rest_framework import viewsets, filters, permissions
from app.restapi.pagination import StandardResultsOffsetPagination
from statistics.restapi.serializers import SalesCommissionsSerializer
from statistics.restapi.permissions import SalesCommissionsListPermissions
class SalesCommissionsViewSet(viewsets.ModelViewSet):
def get_queryset(self):
user_id = User.objects.all()
queryset = User.objects.filter(handling_leads__account_handler=user_id).distinct()
return queryset
serializer_class = SalesCommissionsSerializer
filter_backends = (filters.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter)
filter_fields = (
'id', 'username', 'first_name', 'last_name'
)
ordering_fields = (
'id', 'username', 'first_name', 'last_name',
)
search_fields = (
'id', 'username', 'first_name', 'last_name',
)
pagination_class = StandardResultsOffsetPagination
permission_classes = [permissions.IsAuthenticated, SalesCommissionsListPermissions]
serializer:
from django.contrib.auth.models import User
from rest_framework import serializers
class SalesCommissionsSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('id', 'username', 'first_name', 'last_name')
If you want to filter for users who are 'handling leads', you can do the following:
handling_leads = User.objects.filter(handling_leads__isnull=False)
Here's a link to the documentation: https://docs.djangoproject.com/en/1.10/ref/models/querysets/#std:fieldlookup-isnull
Related
How do I set the lookup_field with a key in JSONField model?
The model:
exchange = models.ForeignKey(StockExchange, on_delete=models.CASCADE, related_name='tickers')
fundamentals = models.JSONField(null=True, blank=True)
The viewset:
class StockCardsV2ViewSet(BaseGetViewSet):
search_fields = ('^fundamentals__General__Name', '^fundamentals__General__Code')
filter_backends = (filters.SearchFilter,)
queryset = Ticker.objects.all()
serializer_class = StockCardsV2Serializer
lookup_value_regex = '[0-9a-zA-Z_.]+'
lookup_field = 'fundamentals__General__Code'
The Serializer:
class Meta:
model = Ticker
fields = ('id', 'url', 'name', 'ticker', 'logo_url', 'currency_symbol', 'sector', 'industry', 'esg_rating',
'weekly_prices', 'monthly_prices', 'yearly_prices', 'two_yearly_prices', 'ad', 'in_watchlist')
lookup_field = 'fundamentals__General__Code'
extra_kwargs = {
'url': {'lookup_field': 'fundamentals__General__Code'},
}
There are no problems with search_fields but I get this error for the lookup_field.
'Ticker' object has no attribute 'fundamentals__General__Code'
Example fundamentals:
"fundamentals": {
"General": {
"CIK": null,
"LEI": null,
"Code": "SATX-WTA",
"ISIN": null,
"Name": "Satixfy Communications Ltd.",
}
},
I want to show only two properties of the model in the list of items, but then in a specific item show all the properties
/api/character <-- show a list with name and id properties
/api/character/30 <-- show all properties of the item with id 30
Code i have in serializer.py:
class CharacterSerializer(serializers.ModelSerializer):
language = LanguageSerializer(read_only=True)
region = RegionSerializer(read_only=True)
realm = RealmSerializer(read_only=True)
faction = FactionSerializer(read_only=True)
race = RaceSerializer(read_only=True)
wow_class = ClassSerializer(read_only=True)
spec = SpecSerializer(read_only=True)
talents = TalentSerializer(many=True, read_only=True)
pvp_talents = PvpTalentSerializer(many=True, read_only=True)
covenant = CovenantSerializer(read_only=True)
soulbind = SoulbindSerializer(read_only=True)
conduits = ConduitSerializer(many=True, read_only=True)
class Meta:
model = Character
fields = ['id', 'name', 'language', 'region', 'realm', 'faction', 'race', 'wow_class', 'spec', 'talents', 'pvp_talents',
'covenant', 'covenant_rank', 'soulbind', 'soulbind_abilities', 'conduits', 'item_level', 'media', 'avatar', 'rating_2v2',
'rating_3v3', 'rating_rbg', 'max_2v2', 'max_3v3', 'max_rbg', 'achievement_points', 'account_achievements', 'seasons',
'alters', 'date_added', 'last_search', 'checked']
code in views.py
class CharacterViewSet(viewsets.ReadOnlyModelViewSet):
serializer_class = CharacterSerializer
permission_classes = []
queryset = Character.objects.all()
filter_backends = [filters.SearchFilter, DjangoFilterBackend]
search_fields = ['name']
filterset_fields = ['language', 'region', 'realm', 'faction', 'race', 'wow_class', 'spec', 'covenant', 'soulbind']
Thx a lot!
Solved.
I have created two serializer for the model one for list and another for detail
class TalentSerializer(serializers.ModelSerializer):
class Meta:
model = Talent
fields = ['id', 'name']
class TalentDetailSerializer(serializers.ModelSerializer):
language = LanguageSerializer(read_only=True)
wow_class = ClassSerializer(read_only=True)
spec = SpecSerializer(many=True, read_only=True)
class Meta:
model = Talent
fields = ['id', 'name', 'language', 'description', 'spell_id', 'talent_id', 'wow_class', 'spec', 'tier_index', 'column_index', 'level', 'icon']
in the viewset I have redefined the get of the class:
class TalentViewSet(viewsets.ReadOnlyModelViewSet):
serializer_class = TalentSerializer
permission_classes = []
queryset = Talent.objects.all()
filter_backends = [filters.SearchFilter, DjangoFilterBackend]
search_fields = ['name']
filterset_fields = ['language', 'spell_id', 'talent_id', 'wow_class', 'spec', 'tier_index', 'column_index', 'level']
def get_serializer_class(self):
if self.action == 'retrieve':
return TalentDetailSerializer
return TalentSerializer
Now works well /api/talent return a list with id and name of items and /api/talent/id return the item with all props of model :)
I am newer in Django rest api. My code is bellow:
class PatientViewSet(viewsets.ModelViewSet):
queryset = Patient.objects.all()
serializer_class = PatientSerializer
filter_backends = (DjangoFilterBackend, filters.OrderingFilter)
filterset_fields = ['id', 'email', 'mobile', 'status', 'type', 'gender']
ordering_fields = ['id', 'name']
def get_queryset(self):
queryset = Patient.objects.all()
status = self.request.query_params.get('status')
name = self.request.query_params.get('name')
if not status:
queryset = queryset.exclude(status="DELETE")
if name:
queryset = queryset.filter(name__icontains=name)
return queryset
def retrieve(self, request, pk=None):
queryset = Patient.objects.all()
patient = get_object_or_404(queryset, pk=pk)
serializer = PatientSerializer(patient)
summary = dict()
summary['payment'] = list(PatientPayment.objects.filter(patient_id=pk).aggregate(Sum('amount')).values())[0]
summary['appointment'] = DoctorAppointment.objects.filter(patient_id=pk).count()
d_appoint = DoctorAppointment.objects.filter(patient__id=pk).last()
appoint_data = DoctorAppointmentSerializer(d_appoint)
summary['last_appointment'] = appoint_data
content = {"code": 20000, "data": serializer.data, "summary": summary}
return Response(content)
Here url is:
http://127.0.0.1:8000/api/patients/2/
When I run in postman it getting the error bellow:
TypeError at /api/patients/2/
Object of type 'DoctorAppointmentSerializer' is not JSON serializable
Here problem with the code snippet:
d_appoint = DoctorAppointment.objects.filter(patient__id=pk).last()
appoint_data = DoctorAppointmentSerializer(d_appoint)
My question is how can I getting my result?
DoctorAppointmentSerializer Class:
class DoctorAppointmentSerializer(serializers.HyperlinkedModelSerializer):
patient = PatientSerializer(read_only=True)
patient_id = serializers.IntegerField()
doctor = DoctorSerializer(read_only=True)
doctor_id = serializers.IntegerField()
doc_image = Base64ImageField(
allow_null=True, max_length=None, use_url=True, required=False
)
doc_file = Base64ImageField(
allow_null=True, max_length=None, use_url=True, required=False
)
class Meta:
model = DoctorAppointment
fields = ['id', 'name', 'mobile', 'problem', 'age', 'gender', 'description', 'doctor', 'doctor_id', 'patient',
'patient_id', 'advice', 'doc_image', 'doc_file', 'created_at']
You have to call the .data property of DoctorAppointmentSerializer class
appoint_data = DoctorAppointmentSerializer(d_appoint).data
^^^^^^
Dog model has a field "cat'
class Dog(models.Model):
...
cat = models.ForeignKey(Cat)
...
class CatSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Cat
# Replace ID with SLUG in urls
lookup_field = 'slug'
fields = ('url', 'slug')
extra_kwargs = {
'url': {'lookup_field': 'slug'}
}
class DogSerializer(serializers.HyperlinkedModelSerializer):
cat= serializers.HyperlinkedRelatedField(
view_name='cat-detail',
lookup_field='slug',
many=False,
read_only=True
)
class Meta:
model = Dog
fields = ('url', 'slug', 'cat')
lookup_field = 'slug'
extra_kwargs = {
'url': {'lookup_field': 'slug'}
}
class CatViewSet(viewsets.ModelViewSet):
def get_serializer_context(self):
context = super().get_serializer_context()
context['slug'] = self.kwargs.get('slug')
return context
queryset = Cat.objects.all()
serializer_class = CatSerializer
lookup_field = 'slug'
class DogViewSet(viewsets.ModelViewSet):
queryset = Dog.objects.all()
lookup_field = 'slug'
serializer_class = DogSerializer
router = routers.DefaultRouter()
router.register(r'cats', rest_views.CatViewSet)
router.register(r'dogs', rest_views.DogViewSet)
How can I set:
read_only=False
The error I get when I set it to False is:
'Relational field must provide a queryset argument, '
AssertionError: Relational field must provide a queryset argument, override get_queryset, or set read_only=True.
cat= serializers.HyperlinkedRelatedField(
view_name='cat-detail',
lookup_field='slug',
many=False,
read_only=False,
queryset=Cat.objects.all()
)
This worked just fine.
I get this error when trying to create a custom Form on the Admin view, I don't see any solution on stackoverflow (yes similar problems) so I think it's a good idea to post it:
My Models.py:
class Webhook(models.Model):
url = models.CharField('URL', max_length = 60, unique = True)
description = models.CharField('Descripcion', max_length = 255)
enabled = models.BooleanField('Enabled', default=True)
event = models.CharField('Evento', max_length=1, choices=Events.EVENTS_CHOICES)
My Forms:
class WebhookForm(forms.ModelForm):
class Meta:
model = Webhook
fields = '__all__'
def save(self, commit=True):
print('saveeeeeee')
webhook = super().save(commit=False)
webhook.code = webhook.id
# Get token
response_token = TOKEN.get()
if response_token['success']:
# Create Webhook
url = 'https://sandbox.bind.com.ar/v1/webhooks'
headers = {
'Content-type': 'application/json',
'Authorization': 'JWT ' + response_token['token']
}
data = {
'url': webhook.url, # Debera responder status_code == 200
'description': webhook.description,
'code': webhook.id,
'enabled': webhook.enabled,
'events': webhook.event
}
data_json = json.dumps(data)
response = requests.put(url, data= data_json, headers = headers)
response_json = response.json()
# Result
result = {}
if response.status_code == 409:
result['success'] = False
result['details'] = response_json
else:
result['success'] = True
result['data'] = response_json
# If ok, Save
if commit & result['success']:
webhook.save()
return result['success']
My Admin.py
class WebhookAdmin(forms.ModelForm): # Only to override a form in admin
class Meta:
model = WebhookForm
fields = '__all__'
# Style to add a new User
add_form = WebhookForm
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('url', 'description', 'code', 'enabled', 'events',)}
),
)
# Style to edit a new User
form = WebhookForm
fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('url', 'description', 'code', 'enabled', 'events',)}
),
)
admin.site.register(Webhook, WebhookAdmin)
And I get this error when I try to do python manage.py makemigrations:
AttributeError: 'ModelFormOptions' object has no attribute 'private_fields'
You have subclassed the wrong thing. The admin class needs to inherit from admin.ModelAdmin, not forms.ModelForm.
ModelAdmin classes don't have an inner Meta class. You need to remove that class altogether.
The Attribute error was because I was trying to assign a Form into the class Meta, and it needs a Model:
class Meta:
model = WebhookForm
fields = '__all__'