首页 文章

Django覆盖保存内联formset

提问于
浏览
1

我现在僵尸化了,正等着有人打我,让我入睡 . 我知道这很简单,因为我是django和python的新手,我做错了 .

我想要一个模型FK字段呈现为文本字段..很容易peasy(不是Linux操作系统)....对吗?

我不这么认为......

好吧,我在SO上有一个解决方案reverse foreign key relationship

但是唉它对我来说不起作用,我尝试过并尝试过......等等...

我把我的代码放在这里,如果任何人为了所有神圣或邪恶的缘故可以帮助我解决这个问题,另外如果可能的话提供一些文档,这样我就可以学习如何在将来自己做这些事情(也教会我如何 grab 鱼... ...我会非常感激,领主会将祝福带给你 .

models.py

class Recipe(models.Model):
    ''' Add/update recipes. User and Guests can update the recipes.
    Requires admin approval for posting recipes unless user is 
    has some privileges. '''
    user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True)
    title = models.CharField(max_length=50, verbose_name=_('Recipe|title'))
    summary = models.CharField(max_length=500, blank=True, verbose_name=_('Recipe|summary'))
    description = models.TextField(blank=True, verbose_name=_('Recipe|description'))
    slug = models.SlugField(unique=True, max_length=50, null=False, blank=False)
    prep_time = models.CharField(max_length=100, blank=True)  # This field type is a guess.
    ctime = models.DateTimeField(auto_now_add=True)
    mtime = models.DateTimeField(auto_now=True)
    sources = models.ManyToManyField(Source, blank=True)
    category = models.ForeignKey(Category)
    serving_string = models.ForeignKey(ServingString, null=True, blank=True)
    serving_value = models.IntegerField(null=True, blank=True)
    DIFFICULTY = Choices((0, 'easy', 'Easy'), (1, 'medium', 'Medium'), (3, 'hard', 'Hard'))
    difficulty = models.IntegerField(choices=DIFFICULTY)
    tag = TaggableManager(help_text="A comma separated list of tags")

class Ingredient(models.Model):
    amount = models.FloatField(null=True, blank=True, verbose_name=_('Ingredient|amount'))
    amountMax = models.FloatField(null=True, blank=True)
    unit = models.ForeignKey(Unit, null=True, blank=True)
    recipe = models.ForeignKey(Recipe)
    food = models.ForeignKey(Food)
    prep_method = models.ForeignKey(PrepMethod, null=True, blank=True)
    order_index = PositionField(blank=True, null=True, unique_for_field="direction")
    direction = models.ForeignKey(Direction, related_name='ingredients', null=True, blank=True)


class Food(models.Model):
    name = models.CharField(max_length=150, verbose_name=_('Food|name'))
    name_sorted = models.CharField(max_length=150, default='', verbose_name=_('Food|name_sorted'))
    group = models.ForeignKey(FoodGroup, null=True, blank=True)
    conversion_src_unit = models.ForeignKey(Unit, related_name='+', null=True, blank=True)
    conversion_factor = models.FloatField(null=True, blank=True)
    name_plural = models.CharField(max_length=150, null=True, blank=True)
    detail = models.TextField(blank=True)
    in_foodguide = models.BooleanField(default=True)

forms.py

class RecipeForm(forms.ModelForm):
    class Meta:
        model = Recipe
        fields = ['title', 'summary', 'description', 'prep_time', 'sources',
                 'category','serving_string', 'serving_value','difficulty', 'tag']

class DirectionForm(forms.ModelForm):
    class Meta:
        model = Direction
        fields = ['text', ]


class FoodForm(forms.ModelForm):
    class Meta:
        model = Food
        exclude = ['name', 'name_sorted', 'group', 'conversion_src_unit', 
                    'conversion_factor', 'name_plural', 'detail', 'in_foodguide']

class IngredientForm(forms.ModelForm):
    food_name = forms.CharField(required=True)
    class Meta:
        model =  Ingredient
        # fields = ['amount', 'amountMax', 'unit', 'prep_method', 'food_name']
        exclude = ('food',)

    def __init__(self, *args, **kwargs):
        super(IngredientForm, self).__init__(*args, **kwargs)
        print 'instance', self.instance
        if self.instance and not self.data:
            try:
                self.initial['food_name'] = self.instance.food.name
                # I added the try block else it RelatedObjectDOesNotExist Error occured.
                # Ingredient has no food
            except:
                pass

    def save(self, commit=True):
        food_name =  self.cleaned_data['food_name']
        name, _ = Food.objects.get_or_create(name=food_name)
                # I printed self.save and it goes into infinite loop.
        instance = self.save(commit=False)
        instance.name = name
        if commit == True:
            instance.save()
        return instance

forms.py - defined inline formset

DirInline = inlineformset_factory(Recipe, Direction, form=DirectionForm, extra=1)
IngInline = inlineformset_factory(Recipe, Ingredient, form=IngredientForm, extra=1)

views.py

def submit_recipe(request):
    recipe_form = RecipeForm()
    dir_formset = DirInline(instance=Recipe())
    ing_formset = IngInline(instance=Recipe())
    if request.method == 'POST':
        recipe_form = RecipeForm(request.POST or None)
        if recipe_form.is_valid():
            recipe = recipe_form.save(commit=False)
            dir_formset = DirInline(request.POST or None, request.FILES, instance=recipe)
            ing_formset = IngInline(request.POST or None, request.FILES, instance=recipe)
            if dir_formset.is_valid() and ing_formset.is_valid():
                recipe.save()
                dir_formset.save()
                ing_formset.save()
                return HttpResponseRedirect(reverse('submit_recipe'))
            else:
                return render(request, 'recipes-orig/submit_recipe.html', 
                                        {'recipe_form':recipe_form,
                                          'dir_formset':dir_formset,
                                          'ing_formset':ing_formset})


    return render(request, 'recipes-orig/submit_recipe.html', 
                                        {'recipe_form':recipe_form,
                                          'dir_formset':dir_formset,
                                          'ing_formset':ing_formset
                                        })

if you feel it is lengthy code to digest quickly I will make a simple version

1 回答

  • 0

    甜土 beans !!我知道我正在做一些愚蠢的事情 . 事实证明我应该在保存中称为超级,我不是......这是代码......但如果可以的话,请参考我的一些文档 .

    forms.py

    def save(self, commit=True):
        food_name =  self.cleaned_data['food_name']
        name, _ = Food.objects.get_or_create(name=food_name)
        instance = super(IngredientForm, self).save(commit=False)
        instance.food = name
        if commit:
            instance.save()
        return instance
    

相关问题