I just installed django-cities-light for my project using DRF and I can't get it work.
My User Model define a city and coutry field as foreignkey, and this is what i get when i tried to get my users :
Could not resolve URL for hyperlinked relationship using view name "city-detail".
You may have failed to include the related model in your API, or incorrectly configured the lookup_field attribute on this field.
Any ideas ?
Thanks !
Using django-cities-light with Rest Framework 3, you need to use their provided view_name:
cities-light-api-{model}-detail
class FooSerializer(HyperlinkedModelSerializer):
url = relations.HyperlinkedIdentityField(view_name="foo-detail")
city = relations.HyperlinkedRelatedField(
view_name="cities-light-api-city-detail", queryset=City.objects.all(),
)
class Meta:
model = Foo
read_only_fields = ('id',)
Related
I had the following serializer. Django Rest Framework allows me to create, update, delete and get info just with this code. Of course I'm adding the serializer to the viewset but the problem is not there:
class MeasurmentSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Measurment
fields = ('id', 'user_statistic', 'value', 'date_created')
I needed to add the detailed info for the field "user_statistic" whenever I GET the data, not just the URL so I added the code in second line and it worked, I got the extra info I needed:
class MeasurmentSerializer(serializers.HyperlinkedModelSerializer):
user_statistic = UserStatisticSerializer(read_only=True) # New Code Added
class Meta:
model = Measurment
fields = ('id', 'user_statistic', 'value', 'date_created')
However the when I POST to the API to create new info into the database it shows the following error:
NotNullViolation: null value in column "statistic_id" of relation
"cms_userstatistic" violates not-null constraint DETAIL:
Failing row contains (55, 6, 0, f, f, null, 2022-01-05, 2022-01-05,
null, 67).
It seems that serializing a related field prevents DRF to get the related field info whenever it tries to create a new object. How can I add the detailed info for that specific related field without breaking the POST request? I wonder if there is another way of getting this info without using the function "to_representation" that allows me to customize the resulting object.
I thank you all for any clue you can give me.
Just serialize your user_statistic into the other field:
from rest_framework import serializers
# ...
class MeasurmentSerializer(serializers.HyperlinkedModelSerializer):
user_statistic_detailed = serializers.SerializerMethodField(read_only=True)
class Meta:
model = Measurment
fields = ('id', 'user_statistic', 'value', 'date_created',
'user_statistic_detailed')
def get_user_statistic_detailed(self, record):
return serialize(UserStatisticSerializer, record.user_statistic)
The Django Rest Framework is not displaying username field in my browsable api html form but when I comment down the username in below code it is showing username field in my browsable api html form. I am new to Django so anyone can please help me here
from rest_framework import serializers
from .models import Note
class NoteSerializer(serializers.ModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='note-detail', lookup_field='pk')
#username = serializers.StringRelatedField(many=False)
class Meta:
model = Note
fields = ['url', 'id', 'username', 'note_text', 'created_date', 'updated_date']
A StringRelatedField is used to denote relations where the target result is computed using the __str__ method. If you look at the source code, you will notice that a StringRelatedField is just read only. Since the value cannot be edited, you don't see it in the browsable API HTML form.
Once you comment that line, the foreignkey relationship is used and it returns the id of the user. In that case, you do see the field username in the form but the value is not a string but an integer.
I don't think there is a way to make a StringRelatedField editable in the form. For more information please have a look at the relates SO post.
The model serializers will automatically generate a set of fields for you based on the model.
I want to make it possible for a json that gives all the model instances to go to a particular instance using the additional url field in the serializer.
There is a view to display the list
class DocumentsListView(viewsets.ViewSetMixin, generics.ListCreateAPIView):
user = serializers.PrimaryKeyRelatedField(read_only=True,)
queryset = Documents.objects.all()
serializer_class = DocumentsSerializer
permission_classes = []
def perform_create(self, serializer):
serializer.save(author=self.request.user)
urls.py
router = DefaultRouter()
router.register('', DocumentsListView)
urlpatterns = [
url('', include(router.urls), name='files')
]
serializers.py
class DocumentsSerializer(serializers.ModelSerializer):
url = serializers.HyperlinkedRelatedField(view_name='documents-detail')
class Meta:
model = Documents
fields = ('id', 'filename', 'datafile', 'type', 'created', 'url')
but got an error
'Relational field must provide a `queryset` argument, '
AssertionError: Relational field must provide a `queryset` argument, override `get_queryset`, or set read_only=`True`.
If I set read_only='True', it works, but url didnt displayed
I've also tried this way of implementing serializer
class DocumentsSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Documents
fields = ('id', 'filename', 'datafile', 'type', 'created', 'url')
but got an error
Could not resolve URL for hyperlinked relationship using view name "doctype-detail". You may have failed to include the related model in your API, or incorrectly configured the `lookup_field` attribute on this field
Recall that every view has a serializer set in serializer_class, and your serializer has a Meta class where you set a model, and thats how you reference the model type you're relating to in HyperLinkedRelatedField. The view_name field is the name of that model followed by '-list' if the url you request does not end with an id(for example when making POST requests), and '-detail' if it does.
Don't know if you eventually solved it but I also experienced something similar, and the solution was changing the HyperlinkedRelatedField to an HyperlinkedIdentityField.
I have two models with one-many relationship (Organization hasMany Locations)
class Organizations(models.Model):
name = models.CharField(max_length=40)
class Location(models.Model):
name = models.CharField(max_length=50)
organization = models.ForeignKey(Organizations, to_field="name", db_column="organization_name", related_name='locations')
class Meta:
db_table = u'locations'
Now, while trying to pre-fetch locations while retrieving "Organizations" I am getting this error.
Organizations.objects.prefetch_related('locations')
AttributeError: Cannot find 'locations' on Organizations object, 'locations' is an invalid parameter to prefetch_related()
However, if I preload the other way around it works fine.
Location.objects.prefetch_related('organization')
Note: After pre-loading organizations from location model, the previous error does not occur anymore.
I am using Django version: 1.8.6
It seems this error is only present in the django shell. This works fine in the django app itself
I have an using the Django admin interface to manage a lot of objects, and one of the page is giving me issue, this page has a field to a related object (Foreign Key) that has a __str__ that also goes to its related objects, this make a lot of queries and is barely useable (Around 3000 queries to show the page as there are a LOT of objects).
I would like to know if there is a way to set a custom queryset ? I would like to add a select_related or prefetch_related to this element.
The part causing issue is this certificate requests list :
The page model (Certificate has the following attribute:
class Certificate(models.Model):
certificate_request = models.OneToOneField(
"CertificateRequest",
verbose_name=_("Certificate request"),
related_name="certificate",
blank=True,
null=True
)
And the related model has this :
class CertificateRequest(models.Model):
domain = models.ForeignKey(
"Domain",
verbose_name=_("Domain"),
related_name="certificate_requests"
)
def __str__(self):
return "{state} certificate request for {domain} from {creation_date}".format(
state=dict(self.STATUS).get(self.status),
domain=self.domain.fqdn,
creation_date=self.creation_date
)
What would be the way to fix this ? How can I set a queryset on this part ?
EDIT: I added more informations.
I tried using a custom form, but this didn't do any change :
class CertificateForm(forms.ModelForm):
certificate_request = forms.ModelChoiceField(queryset=CertificateRequest.objects.select_related("domain"))
class Meta:
model = Certificate
fields = "__all__"
#admin.register(Certificate)
class CertificateAdmin(CompareVersionAdmin):
model = Certificate
class Meta:
form = CertificateForm
You can create a custom ModelForm for your admin where you specify a ModelChoiceField for the ForeignKey. Here you can specify the queryset parameter:
# forms.py
class MyForm(forms.ModelForm):
certificate_request = forms.ModelChoiceField(queryset=CertReq.objects.foo().bar())
# select/prefetch-------^^^^^^^^^^^
class Meta:
model = Foo
# admin.py
class YourAdmin(ModelAdmin):
form = MyForm
The get_object method on the ModelAdmin class is what is responsible for retrieving the object to edit. You could certainly extend that method in your subclass to use select_related as necessary.