1

I'm trying to serialize a model that has a OneToOneField that stores a specific user profile. Since that user profile is used to retrieve the user's instance of that model, I can't remove it from the model, but I think it's causing my problems when I'm trying to serialize and send JSON data. I'm not sure if I explained that well since I'm very new to Django, but hopefully it will be clearer later.

Here is what the model basically looks like:

class ModelName(models.Model):
    profile = models.OneToOneField(Profile)
    other_field = models.BooleanField(default = True)
    etc_field = models.CharField()
    ...

Here is what my serializer looks like:

class ModelNameSerializer(serializers.ModelSerializer):
    class Meta:
        model = ModelName
        fields = ('other_field', 'etc_field', ...)

When I call the serializer, I do so after a post_save signal is sent. That is to say, I have a receiver that uses the newly saved model instance to serialize the model's data into JSON. Here's what that looks like:

@receiver(post_save, sender=ModelNameForm, dispatch_uid='uniquestring')
def arc_update(sender, instance, **kwargs):
    serializer = ModelNameSerializer(instance)
    print(serializer.data)

Of course, the print statement in the console is for debugging so that I can test that the signal is being sent, received, and executed properly. However, it prints this:

{'other_field': data, 'etc_field': data, ...}
{}

I know that the empty data set is trying to print the profile data, because when I had kept the profile field in, it was printing this:

{'profile': 1, 'other_field': data, 'etc_field': data, ...}
{'profile': 1}

But I don't know how to get rid of that extra profile print. At first I thought it was being called multiple times, which is what the dispatch_uid was added for, but this didn't fix anything. How do I get rid of that extra serialization of the profile?

Thanks!

UPDATE:

The ModelName instance being sent to the receiver is called in views.py, where the user is filling in a form containing other_field and etc_field and so on and so forth. This is what that looks like:

@login_required
def modelname(request):
    user = get_object_or_404(User, username=request.user)
    profile, created = Profile.objects.get_or_create(user=user)
    modelname, created = ModelName.objects.get_or_create(profile=profile)
    context = {}
    form = ModelNameForm(request.POST or None, instance=modelname)
    context.update({"form": form})
    if request.method == 'POST':
        if form.is_valid():
            form.save()    #This is sending the post_save signal
            ...
    return render(request, ...)

Also, as requested, here is the form code!

class ModelNameForm(forms.ModelForm):
    class Meta:
        model = ModelName
        fields = ['other_field', 'etc_field', ...]
Serjik
  • 10,543
  • 8
  • 61
  • 70
aevumcessi
  • 61
  • 8
  • http://stackoverflow.com/questions/27935558/dynamically-exclude-or-include-a-field-in-django-rest-framework-serializer – Shang Wang Dec 15 '15 at 18:34
  • @ShangWang The problem isn't that I'm unable to exclude certain fields, I think, since I was able to omit the profile field from the serialization. The problem is that it still tries to serialize something from the Profile model, probably because it's attached to ModelName so it's trying to serialize Profile. – aevumcessi Dec 15 '15 at 18:46
  • So you've `post_save` receiver for `ModelNameForm`? Basically you're passing a `Form` instance to `Serializer`? Can you verify this thing? Can you see if your serializer is valid? Print `serializer.is_valid()`. – Rohit Jain Dec 15 '15 at 18:48
  • @RohitJain If I try to call serializer.is_valid() I get an error that says, "Cannot call `.is_valid()` as no `data=` keyword argument was passed when instantiating the serializer instance." However, this also happens when I change it to `sender=ModelName` instead of `sender=ModelNameForm`. The reason I changed it to `ModelNameForm` is that if I do `sender=ModelName`, it prints the data twice and I'm also not sure why that happens since I have the dispatch_uid in there... – aevumcessi Dec 15 '15 at 18:57
  • @aevumcessi Can you show how and where you're creating `ModelName` instance? – Rohit Jain Dec 15 '15 at 19:01
  • @RohitJain Just updated the post! – aevumcessi Dec 15 '15 at 19:06
  • Ok, so if your signal is on `ModelName`, then it would be called twice. Once from `get_or_create(profile=profile)` and another from `form.save()`. That is why, first time you didn't have `other_fields` and `etc_field`, and after form save, you got them. Instead of `get_or_create`, can you just do: `ModelName(profile=profile)`, if instance doesn't exist with that `profile`. That way, it will be created only on `form.save()` – Rohit Jain Dec 15 '15 at 19:07
  • @RohitJain If I do ModelName(profile=profile), I get an error that says `'ModelName' object is not iterable`? – aevumcessi Dec 15 '15 at 19:13
  • Where are you getting that error? – Rohit Jain Dec 15 '15 at 19:14
  • @RohitJain I get this error after I try to update the form, right after it tries to POST – aevumcessi Dec 15 '15 at 19:16
  • @aevumcessi Are you iterating over the `ModelName` bound object in the template in `GET` request? That line won't give you such error. – Rohit Jain Dec 15 '15 at 19:20
  • @RohitJain I'm not sure exactly what that means (new to Django), but I think you're asking if it goes through the fields that ModelName needs, right? In that case, it is, since it needs to retrieve the ModelNameForm with all of the fields of ModelName in order to create or update the ModelName instance for that user. – aevumcessi Dec 15 '15 at 19:25
  • @aevumcessi No, I mean are you iterating over `ModelName` instance in your html `template` file where this form is rendered? Can you post your template file? – Rohit Jain Dec 15 '15 at 19:26
  • What does your form code look like? Also, why not use the serializer to save your data, rather than a form? – Joey Wilhelm Dec 15 '15 at 19:29
  • @RohitJain http://pastebin.com/0zHKJGhX This is the template file! – aevumcessi Dec 15 '15 at 19:30
  • @JoeyWilhelm Can you use the serializer to save data from a page which asks the user to update or fill in a form? I will update the post with the form code in a few seconds. – aevumcessi Dec 15 '15 at 19:32
  • @aevumcessi Something is fishy here. That `ModelForm` and the template you showed, shouldn't throw that error. Are you sure you aren't missing anything important here? What are those `...` for in fields list? – Rohit Jain Dec 15 '15 at 19:59
  • @aevumcessi Can you try moving `ModelName` and `Profile` object creation inside the `if request.method == 'POST'` block? I mean, for `GET` request, you don't need to pass `instance` argument to the `form`. Just add `ModelNameForm()` to context. See if this change fixes things. – Rohit Jain Dec 15 '15 at 20:17
  • @RohitJain But don't you need the instance to fill out a previously saved version of the form? That way in the GET request, when the page loads, the user will not have to fill in everything they have already filled out. Also, the `...` in the fields list are just for other fields in the model that need to be filled out. – aevumcessi Dec 21 '15 at 23:29

0 Answers0