如何从一个模型中获取值以在Dj​​ango中出现在另一个模型中

时间:2018-06-24 00:14:00

标签: django django-forms django-rest-framework

我是Django的新手,所以请保持友善-_ ^。

我有两个模型“猫”和“垃圾”。

垃圾包含两个带有名称的元素。

我有一堆猫。

我想要它,以便作为用户,我可以根据猫砂模型中现有的猫砂名称将任何猫与猫砂相关联。

我该如何实现?

(我已经尝试过“一对多”,“多对多”和“反向关系” ...对于DJANGO来说,我是新手,所以我不认为这些尝试中的任何一项都可以正确完成。

这是我当前的模特。py

...
class Litter(models.Model):
    name = models.CharField(max_length=255)
    notes = models.CharField(max_length=2048, blank=True, null=True)

    created = models.DateTimeField(blank=True, null=True)
    modified = models.DateTimeField(blank=True, null=True)

    def save(self, *args, **kwargs):
        # Save time Litter object modified and created times
        self.modified = datetime.datetime.now()
        if not self.created:
            self.created = datetime.datetime.now()

        super(Litter, self).save(*args, **kwargs)

    def __str__(self):
        return self.name


class Cat(models.Model):
    litter_mates = models.ManyToManyField(Litter)

    GENDER_CHOICES = (
        ('M', 'Male'),
        ('F', 'Female')
    )
    MALE = 'M'
    FEMALE = 'F'

    CAT_TYPE = (
        ('O','Orphan'),
        ('P','Pregnant'),
        ('N','Nursing')
    )
    Orphan = 'O'
    Pregnant = 'P'
    Nursing = 'N'

    name = models.CharField(max_length=255)
    slug = models.SlugField(unique=True, blank=True, null=True)

    reference_id = models.CharField(max_length=255, blank=True, null=True)
    short_name = models.SlugField(max_length=255, blank=True, null=True,
                                  help_text="This name is auto generated from the name and reference ID. "
                                            "It is used to make it easy to find the animal in a URL lookup.")

    gender = models.CharField(max_length=1, choices=GENDER_CHOICES, default=MALE)
    cat_type = models.CharField(max_length=1, choices=CAT_TYPE, default=Orphan)
    color = models.CharField(max_length=255, blank=True, null=True)
    weight_unit = models.CharField(max_length=2, choices=Weight.MEASURE_CHOICES, default=Weight.GRAMS)
    weight = models.IntegerField(blank=True, null=True)
    notes = models.TextField(blank=True, null=True)
    birthday = models.DateTimeField(blank=True, null=True)
    photo = models.FileField(upload_to="kitty_photos", blank=True, null=True)
    created = models.DateTimeField(blank=True, null=True)
    modified = models.DateTimeField(blank=True, null=True)

    alert_feeder = models.BooleanField(default=False,
                                       help_text='Alert feeder to critical situations')
    critical_notes = models.TextField(blank=True, null=True)

    first_weight_loss = models.BooleanField(default=False)
    second_weight_loss = models.BooleanField(default=False)
    third_weight_loss = models.BooleanField(default=False)
    many_weight_losses = models.BooleanField(default=False)

    def save(self, *args, **kwargs):

        # Check to see if slug exists, if it does, make a counter
        self.slug = orig = slugify(self.name)

        for x in itertools.count(1):
            if not Cat.objects.filter(slug=self.slug).exists():
                break
            self.slug = '%s-%d' % (orig, x)

        self.modified = datetime.datetime.now()
        if not self.created:
            self.created = datetime.datetime.now()
        self.short_name = slugify("{name}-{reference_id}".format(name=self.name, reference_id=self.reference_id))

        super(Cat, self).save(*args, **kwargs)

    @models.permalink
    def get_absolute_url(self):
        return 'tracker:cat', (self.slug,)

    def __str__(self):
        return self.name

...

这是我的serializers.py

...
class LitterSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Litter
        fields = (
            'id',
            'name',
            'notes'
        )


class CatSerializer(serializers.HyperlinkedModelSerializer):
    litter_mates = LitterSerializer(many=True)

    class Meta:
        model = Cat
        fields = (
            'id',
            'name',
            'slug',
            'reference_id',
            'short_name',
            'gender',
            'cat_type',
            'litter_mates',
            'color',
            'weight_unit',
            'weight',
            'notes',
            'birthday',
            'photo',
            'created',
            'modified',
            'alert_feeder',
            'critical_notes',
            'first_weight_loss',
            'second_weight_loss',
            'third_weight_loss',
            'many_weight_losses'
        )

    def create(self, validated_data):
        litter_data = validated_data.pop('tracks')
        cat = Cat.objects.create(**validated_data)
        for litter_data in litter_data:
            Litter.objects.create(cat=cat, **litter_data)
        return cat


...

现在,我想知道是否可以在http://localhost:8000/api/v1/cats/上获得我的管理页面,以向我展示创建/更新包含“ litter_mates”下拉列表的猫形表格,其中包含我的两个猫砂的名称...我将有我需要的东西。

感谢您的光临。

已更新:

这也是我的 admin.py

from __future__ import unicode_literals
from django.contrib import admin
from jsoneditor.forms import JSONEditor
from django.contrib.postgres.fields import JSONField
from . import models as tracker_models
from import_export.admin import ImportExportModelAdmin
from import_export import resources


class LitterResource(resources.ModelResource):

    class Meta:
        model = tracker_models.Litter


class MedicationResource(resources.ModelResource):

    class Meta:
        model = tracker_models.Medication


class FeedingResource(resources.ModelResource):

    class Meta:
        model = tracker_models.Feeding


class CatResource(resources.ModelResource):

    class Meta:
        model = tracker_models.Cat


class LitterAdmin(ImportExportModelAdmin):
    search_fields = ['name']
    list_display = ['name', 'created', 'modified']
    resource_class = LitterResource


class MedicationAdmin(ImportExportModelAdmin):
    search_fields = ['cat__name', 'notes']
    list_display = ['cat', 'duration', 'notes', 'frequency', 'dosage', 'dosage_unit',
                    'created', 'modified']
    resource_class = MedicationResource


class FeedingInline(admin.TabularInline):
    model = tracker_models.Feeding
    extra = 1
    exclude = ['modified']
    readonly_fields = ['created']


class FeedingAdmin(ImportExportModelAdmin):
    search_fields = ['cat__name', 'amount_of_food_taken', 'notes']
    list_display = ['cat', 'weight_unit_measure', 'weight_before_food', 'food_unit_measure', 'amount_of_food_taken',
                    'food_type', 'weight_after_food', 'stimulated', 'stimulation_type', 'notes', 'photo',
                    'created', 'modified']
    resource_class = FeedingResource


class CatAdmin(ImportExportModelAdmin):
    search_fields = ['name', 'reference_id', 'short_name', 'gender', 'notes']
    list_display = ['name', 'reference_id', 'short_name', 'gender', 'weight_unit', 'weight', 'notes', 'birthday', 'photo',
                    'alert_feeder', 'critical_notes', 'first_weight_loss', 'second_weight_loss', 'third_weight_loss',
                    'many_weight_losses', 'created', 'modified']
    inlines = [
        FeedingInline
    ]
    resource_class = CatResource


__custom_admins__ = {
    'Cat': CatAdmin,
    'Feeding': FeedingAdmin,
    'Medication': MedicationAdmin,
    'Litter': LitterAdmin,
}

for model in tracker_models.__admin__:
    params = [getattr(tracker_models, model)]
    if model in __custom_admins__:
        params.append(__custom_admins__[model])
    else:
        _dyn_class = type('%sAdmin' % ( model,), (admin.ModelAdmin,), {})
        params.append(_dyn_class)
    admin.site.register(*params)

admin.site.site_title = 'KittyTracker Admin'
admin.site.site_header = 'KittyTracker Admin'

更新两次:

现在当我转到“ http://localhost:8000/api/v1/cats/”时,出现以下错误...

django.db.utils.ProgrammingError

django.db.utils.ProgrammingError: column tracker_cat.litter_id does not exist
LINE 1: SELECT "tracker_cat"."id", "tracker_cat"."litter_id", "track...

1 个答案:

答案 0 :(得分:0)

我会在您的Cats模型中使用多对一关系。 这样,您就可以将猫分配给一个猫砂,该猫砂可以容纳许多猫。

class Cat(models.Model):
...
litter = models.ForeignKey(Litter, on_delete=None)
...