0

Hello i have created a simple model and now i want to access the data in another model to view it later on.

My model looks like this:

from django.db import models
class A(models.Model):
    asd = models.CharField(max_length=50,default="DEFAULT VALUE")
    def __str__(self):
        return(self.asd)

Now i want a second model in which i get the data from the first model and add each element to a list or something like that. For Background i am doing this like so, so i can create a drop down widget with choices that can be changed and added to in the admin page.

I was first thinking of creating another model or form and came up with this, though it doesn´t work:

#this is not in the model.py file
from .models import A
class B(forms.Form):
    a = A.objects.all()
    b = []
    for i in range(len(a)):
        b.append(a[i])
    c = forms.ChoiceField(choices=b)
James
  • 317
  • 3
  • 12
  • You should probably follow a python and Django tutorial before attempting to build this. Your problem is too broad and there are too many issues with your current code that show lack of understanding of basic python/Django features. – Geekfish Apr 17 '19 at 11:49
  • well since my error message tells me that A is not iterable it shows me that it´s not a list i am getting with .objects.all() . This is confusing since when using a shell and trying out my code in the exact same way i get a list b with the elements of the model. The main question still is, how do i access the data from the model in the database for further use. – James Apr 17 '19 at 11:53
  • Since you have not shown the error, we can't possibly know that. But this code would not actually raise that error. You should post the actual code and the full traceback. Still, as Geekfish says, there are several things here that you should not do in either Django or Python more generally. – Daniel Roseman Apr 17 '19 at 12:03
  • `objects.all()` returns a `QuerySet`. Just testing it in the shell may work, but this is not how you should be iterating over a QuerySet (or a list for that matter), or using it in a form. Not trying to be dismissive as these are normal beginner mistakes, but as I said, there's too many things wrong with the current implementation, you may find it more productive to build stuff with Django forms from tutorials first. You should also look into [ModelChoiceField](https://docs.djangoproject.com/en/2.2/ref/forms/fields/#django.forms.ModelChoiceField), which is more appropriate for your problem. – Geekfish Apr 17 '19 at 12:03
  • my traceback is this: Exception Type: TypeError at / Exception Value: 'A' object is not iterable. I just read about object.all() creating a QuerySet in the documentation. I understand now why i can´t iterate over this object, though i don´t understand why it´s generally bad practice to iterate like this over lists? For a QuerySet it makes sense but a list ? – James Apr 17 '19 at 12:07
  • A traceback includes the full *trace*, which is all the lines above the final error message, which show all the function calls and files involved in your request. It is also clear from your error that it happens in code that you have not included here. – Geekfish Apr 17 '19 at 12:09
  • i cannot include the full traceback since its too long for a comment – James Apr 17 '19 at 12:13
  • You can absolutely iterate over Querysets. But this is not the way to iterate in python, you should be using `for item in iterable`, no range/len etc. You should also not be iterating a Queryset like this at the class level on a Django Form. This is much more complex to understand if you don't take the slow way and study the language and framework. Reg trace. You can always update your original question with more code and info. – Geekfish Apr 17 '19 at 12:14
  • 1
    No-one asked you to post the traceback in a comment. Edit the question and post it there, properly formatted. – Daniel Roseman Apr 17 '19 at 12:18
  • well i just used the ModelChoiceField like Geekfish suggested and it worked perfectly with A.objects.all() – James Apr 17 '19 at 12:22

1 Answers1

1

Django allows you to create class methods using @classmethod decorator. You can use that to pass data from first model into second model. Take a look at example below.

First model:

from django.db import models
class A(models.Model):
    asd = models.CharField(max_length=50,default="DEFAULT VALUE")
    def __str__(self):
        return(self.asd)

    # This is important
    @classmethod
    def get_all_choices(cls):
        # I still suggest you to go through Django documentation
        # to understand what query sets are
        return cls.objects.values_list('asd', flat=True)

Second model:

from django.db import models
from a.models import A
class B(models.Model):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.choice_array = A.get_all_choices()

    choices = models.CharField(max_length=10, choices=self.choice_array)

Please observe the comments. If you need to understand how to import A into B, refer to this question - Django : Unable to import model from another App

I have done this a couple of times but don't have the setup in hand to try. There might be some errors which you need to resolve on your own by reading the error messages.

nightgaunt
  • 890
  • 12
  • 30
  • i like this way of implementing models into other models, allthough i have gotten what i wanted with using forms.ModelChoiceField and the QuerySet i will remember this. Thanks – James Apr 17 '19 at 12:25
  • This is a very hacky/duct tape attempt at doing a thing that Django already has simple features for. It's literally why `ForeignKey` fields exist in models, and why `ModelFields` exist in Forms. – Geekfish Apr 17 '19 at 12:26
  • `ForeignKey` is definitely the way if you are starting fresh. But often, adding a foreign key on an existing data set can cause complications with migration (especially when the application is so big that you can't trace the impact). But since OP has specifically asked for a case where he can tweak tables, I accept this is not the right answer. – nightgaunt May 08 '19 at 08:51