Переопределение Django Сохранить на встроенной форме
Сейчас я зомбирован и жду, когда кто-нибудь ударит меня и уложит спать. Я знаю, что это просто, и так как я новичок в django и в python, я делаю это неправильно.
Я хотел, чтобы поле модели FK отображалось в виде текстового поля. Простота (не в ОС Linux).... верно?
Я так не думаю...
ну, у меня есть одно решение для SO обратного отношения внешнего ключа
но увы у меня не получилось и я попробовал и попробовал и попробовал... и так далее...
Я размещаю свой код здесь, и если кто-то ради всего святого или злого может помочь мне в этом, и дополнительно, если возможно, предоставить некоторую документацию, чтобы я мог научиться делать эти вещи самостоятельно в будущем (также научите меня ловить рыба)... Я был бы очень благодарен, и Господь наградит вас своим благословением.
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 - определенный встроенный набор форм
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
})
если вы чувствуете, что это длинный код, чтобы быстро переварить, я сделаю простую версию
1 ответ
Сладкая картошка!! Я знал, что делал что-то глупое... оказывается, я должен был вызвать super в save, чего я не делал... вот код... но, пожалуйста, обратитесь к какой-нибудь документации, если можете.
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